Our error handling Middleware is looking pretty good.
But as I've said several times just one or two quick more things.
So the next thing I want to take a look at is inside this middleware.
I just want to really study these two if statements for a moment.
At present we are checking to see if the error is of type request validation error or database connection
error if it is.
We then call the errors serialize errors method stick it into this bigger object and then send the result
back to the user.
There's a very big potential for a mistake inside of here right now let's imagine for a second that
someone is building out a new custom error class.
So let's imagine that we are building out to request validation error for the very first time.
And I sit down to implement this serialize errors function.
So let's imagine we're writing this out for the very first time and maybe for some accidental reason
we make a little typo in message.
Maybe I type in mage instead of message.
At present there is absolutely nothing inside of our typescript code to verify and make sure that serialize
errors is put together correctly.
It would be really nice if we had some kind of check inside of our code something to make sure that
serialize theirs is always going to return.
This kind of structure right here that nice array of objects that we are doing all this work to make
sure we get the right now and these errors flow into our error handling middleware.
We're just checking to see if we have an instance of database connection error or request validation
error.
If we do so if we say yes that's what these this error is our air handler Middleware is pretty much
just saying Gee I sure hope you implemented that serialize errors function correctly.
It's really just a hope it would be kind of nice to actually have something in the typescript world
to just double check and make sure that these custom errors have the correct implementation of serialized
errors that would be something really nice to add in because we'd make sure that as we start to add
some additional custom error classes in the future we want to make sure that we've always creating a
custom area that has a status code that's a number and has a serialized errors function that's going
to return the correct structure of data as again we're going through all this extra effort just to make
sure that all of our different servers that we're gonna create over time are always going to return
the exact same structure of error.
So again it'd just be really great to make sure that we had something inside the typescript world to
double check that.
So how can we do this.
Well there are two possible approaches.
Here's option number one.
Option number one.
We could create a new file inside of our ears directory and we would call this file something like custom
air inside there we would define an interface called Custom air so inside this custom air interface
we would define what it means to be a customer.
We could say that in order to be a customer you must have a status code that is a number and you must
implement a serialized erase function that returns an array of objects that has a message property and
possibly a field property we could then import that into our request validation and database connection
files and use that implements keyword to make sure that those classes correctly implement that interface.
Now this is a very very viable option.
Absolutely not anything inherently wrong with this.
And because that I want to is very quickly like really quickly write out the code to do something like
this just to make sure it's really crystal clear.
Now we are gonna delete this code immediately.
Again I just wanna give you a very quick example.
So you do not have to write this out if you don't want to.
So as an example normally I would define this interface inside of a separate file but just to save some
time all right the interface directly inside of request validation error but it could do something inside
of here like customer.
We could say that in order to be a customer you have to have a status code that is a number and you
must have a serialized erase function that's going to return an array of objects and each of those objects
should have a message that is a string and optionally a field the question mark right there says that
field is not necessary but you can optionally provide it.
So now that this interfaces put together we can make sure that our custom class satisfies this interface
by writing onto the very end of the class declaration implements custom air.
Like so now this is double check going to double check and make sure that I've got a status quo that
has a number and a function called serialize errors that returns an array of objects that look like
that as soon as I add on implements custom air I can scroll down and see that I've now gotten error
around serialize errors.
And that's because I have a function it is called serialize errors but is returning the incorrect structure
of data rather than saying message.
It says mage.
And so this would help me catch errors in my code.
It would help make sure that I always write out custom errors with the correct structure or status code
and serialize errors so again this is an absolutely viable option but it's not quite what we're gonna
do this time around.
So I'm going to delete that interface and implements on the very end as well.
So what are we gonna do instead.
Well we're going to take a very similar approach but instead of using an interface we're gonna do something
slightly different.
We're going to create a new abstract class called customer the abstract class is going to serve the
exact same purpose as the interface that we just looked at.
So it's going to set out a number of properties that must be defined in order to be considered to be
a custom error.
If you're not familiar with abstract classes in general and typescript couple of reminders on them an
abstract class is like a class but it can not be directly instantiated in other words we cannot say
new custom air instead custom or semi abstract classes are used to organize our code and somehow setup
requirements or subclasses of this class.
So really it's being used to set up a requirement for a subclass.
The nice thing about a abstract class is that when we translate this over to javascript to actually
execute we actually do end up with a class definition when we translate interfaces to JavaScript all
interfaces fall away.
They don't actually exist in the world of javascript but abstract classes do.
And that means that we can use an abstract class with an instance of check and that's extremely relevant
because remember back over inside of our area handling middleware it is right here we are doing some
instance of checks if we continue with the same pattern that we have right here.
We would eventually have to have a ton of different if statements for all the different kinds of errors
and so we start to run into that issue again where are error handling middleware starts to get really
bloated but if all these custom errors are going to be extending some custom based class of customer
right here we can instead just have one single instance of checks something that says is the error an
instance of custom error subclasses of this custom air abstract class will satisfy this instance of
check.
So we will only have to write out that if statement one time and that will capture all possible customer
errors that ever get thrown inside our application.
So long story short rather than defining an interface and having our classes implemented we're going
to instead define a abstract class called customer and we're going to have request validation and database
connection error.
Extend that abstract class Oh I know this stuff is nasty isn't it.
This is why learning this stuff this is why you go and get a job and get paid the big bucks is because
this stuff is just ridiculous sometimes.
I know this is just really challenging stuff right now and I know it's a lot of typescript stuff and
it's not really specific to the world of micros services but this is stuff where again you gotta make
sure same thing this is all about.
We have to make sure that the air's coming out of our services are always satisfying that same structure
and it is by doing stuff like this right here literally exactly this that we're going to make sure that
all the different errors we ever create inside our application have that identical structure.
If you tried doing all this stuff with javascript I can guarantee you you would start to run into errors
almost immediately and I say errors I mean bad errors not these actual handle errors that we're talking
about know this typescript stuff is nasty but this is how we implement structure inside of really large
code bases it's just how it's done and it's what we have to do to implement micro services in some reasonable
fashion.
OK.
So a little bit of a spontaneous pep talk there anyways.
Let's take a pause right here.
We're gonna come back next video start to implement this abstract class.