Better Error Handling


00:00 There's a saying in software development that exceptions are for exceptional

00:03 circumstances, and that is exactly what we will cover in this lesson.

00:07 We will look at a few JavaScript examples and even discuss how this relates to

00:10 Asing Await. So let's go.

00:14 We bring in some utilities from a vendor file and a key utility over here is the

00:18 email validator. And when we say validator,

00:21 we basically mean that it's going to take a value and it's either going to

00:24 return true or false based on if it is a valid email or not.

00:29 Now our objective is to do a nice a p I design for this validate function that

00:33 takes a value and a set of validators and then has to indicate if the value is

00:37 valid. And if it is not valid, it wants to provide a custom error message. Now,

00:42 determining if it is valid or invalid is actually quite easy.

00:45 We can simply loop through all of the validators,

00:48 invoke them with the value and see if any of them says that it is false. Now,

00:52 there are a number of validation libraries out there that get the next step

00:55 wrong. If the value is valid, they will return the valid value,

00:59 otherwise they will throw an error. Now,

01:01 even though you might think that this is perfectly fine,

01:03 let's look at an example that demonstrates why this is not a good idea.

01:08 Consider the user that wants to write the submit function that takes an email,

01:11 runs them through the validate function and wants to see if it comes out as

01:15 valid or not. Because we've gone with an exception throwing model,

01:18 we have to write our call to validate with the try-catch. Now,

01:22 there are a few reasons why this is not ideal Within the catch,

01:25 there is no guarantee that the error is coming from the validate function as

01:29 they might have just made a mistake within the try block themselves. Now,

01:32 that's not true for this particular case.

01:34 But another issue that can happen is that the email validator might throw an

01:38 exception when it is invoked by the validate function.

01:41 And now when the validate function calls this particular validator,

01:44 this will still get caught by our catch and we would expect just the error from

01:48 the else block.

01:49 But we are actually getting an error from the email validator and this has

01:53 nothing to do with the email being invalid.

01:55 Perhaps there is a bug within the email validator and instead of being caught as

01:58 a bug within our code,

01:59 is it actually being converted into an error in the user's input?

02:03 Now the alternative approach is quite simple.

02:05 You can perhaps return a bullion value that is true for valid and false for

02:09 invalid. Or if you do want to return a value or an error message,

02:13 you can return to different kinds of objects. If it is a valid value,

02:17 you return an object containing the value member. And if it is invalid,

02:21 you return an object containing an error message.

02:23 We simply annotate our function with this new type and then replace the return

02:27 of the value with the return of an object containing the string value and then

02:32 replace the throw with an object that contains the error string.

02:35 And now we can modify the code within our submit function to be a bit more

02:39 reliable as it's not catching everything that might go wrong within our call

02:42 stack. We simply check the results that is returned from the validate function.

02:46 If it has an error property,

02:48 this means that it is not a valid value and we can notify the user of the error

02:51 within the email. Otherwise we simply save the result of value.

02:57 So really the key

02:59 Takeaway over here is that we shouldn't be throwing an error in our code unless

03:02 we want it to bubble far, far away all the way to our program's exit log.

03:06 Now things get even a bit more interesting when you consider Async away.

03:10 So let's take a look.

03:12 We will look at a simpler example with Async Away because even people that would

03:16 never throw an exception would still quite happily reject a promise.

03:20 Haing have a function called is negative, that takes a value.

03:23 And by returning a promise and based on some super complicated complex logic,

03:27 we would either resolve it with the value or we will reject the promise with a

03:31 custom error message. Now,

03:33 using promise resolution and promise rejection to separate different kinds of

03:37 returns is not a good idea.

03:39 Here's some code that is a similar kind of thing that we did before. We,

03:42 we take an input value,

03:43 we want to see if it is negative or not using this is negative utility and now

03:48 we have to wrap it in a try-catch if you want to get this error message.

03:51 Because when you await a promise that is going to reject it is essentially going

03:55 to throw an exception at that particular point in the call stack. Now,

03:58 the proper approach will be very similar to the approach that we took in the

04:01 synchronous version. Essentially,

04:03 you should think of the return statement within a synchronous version,

04:06 the same as a promised resolution and a throw in the synchronous version,

04:10 the same as a promised rejection.

04:12 So we replace our rejection with the resolution containing an object that has

04:16 the error property and the successful return as a resolution containing the

04:21 value property. And now within our Async eight,

04:23 we can do the same thing that we did before. We no longer need the try-catch.

04:27 We simply get the result, see if it has the error property,

04:31 and then notify the user about the error. Otherwise, we save the input.

04:36 So to recap, don't throw errors unless you need to.

04:39 And if you are working with Async Away, which most of us are,

04:42 show your rejections the same love that you would show your throw statements.

04:46 And if you are working with someone that loves to throw and reject,

04:49 then share this with you, with them.

04:50 Smash the like and subscribe for more content like this.

04:53 And I will see you in the next one.