1 00:00:01,070 --> 00:00:01,950 All right! 2 00:00:01,950 --> 00:00:04,040 And now to finish this section, 3 00:00:04,040 --> 00:00:07,043 let's learn how to catch uncaught exceptions. 4 00:00:08,660 --> 00:00:11,930 But what exactly are uncaught exceptions? 5 00:00:11,930 --> 00:00:15,290 Well, all errors, or let's also call them bugs, 6 00:00:15,290 --> 00:00:17,280 that occur in our synchronous code 7 00:00:17,280 --> 00:00:21,230 but are not handled anywhere are called uncaught exceptions. 8 00:00:21,230 --> 00:00:25,340 And like before, so just like with the unhandled rejections, 9 00:00:25,340 --> 00:00:28,730 we also have a way of handling uncaught exceptions. 10 00:00:28,730 --> 00:00:30,720 So let me quickly show you 11 00:00:30,720 --> 00:00:32,823 an example of an uncaught exception. 12 00:00:34,370 --> 00:00:37,400 So let's simply pretend that we're trying 13 00:00:37,400 --> 00:00:40,423 to console.log something that doesn't exist. 14 00:00:42,110 --> 00:00:46,600 And so right away, we get this error here, x is not defined, 15 00:00:46,600 --> 00:00:50,080 and then by default, we get this entire stack trace here 16 00:00:50,080 --> 00:00:51,960 printed to the console. 17 00:00:51,960 --> 00:00:52,793 All right. 18 00:00:52,793 --> 00:00:57,660 And now, to fix this, this is very similar to doing 19 00:00:57,660 --> 00:00:59,380 the unhandled rejections. 20 00:00:59,380 --> 00:01:02,040 So again, we're listening to an event, 21 00:01:02,040 --> 00:01:04,040 this time it's called uncaughtException. 22 00:01:08,662 --> 00:01:11,912 And of course it needs to be in quotes. 23 00:01:12,840 --> 00:01:17,390 And then just like before, we pass in our callback function. 24 00:01:17,390 --> 00:01:18,223 Okay. 25 00:01:18,223 --> 00:01:20,960 And now actually what we're doing here is very similar 26 00:01:20,960 --> 00:01:22,350 to what we did here. 27 00:01:22,350 --> 00:01:24,970 So we wanna lock the error to the console 28 00:01:24,970 --> 00:01:29,690 so that it then shows up in the logs in our server, okay? 29 00:01:29,690 --> 00:01:32,430 So, giving us a way of then fixing the problem. 30 00:01:32,430 --> 00:01:35,223 And then we want to gracefully shut down the server. 31 00:01:36,750 --> 00:01:39,010 So let's, well actually here I want 32 00:01:39,010 --> 00:01:41,590 to print the entire error to the console, 33 00:01:41,590 --> 00:01:43,940 and not just the message, okay? 34 00:01:43,940 --> 00:01:45,993 And let's also change the order here, 35 00:01:47,300 --> 00:01:48,660 but that's it. 36 00:01:48,660 --> 00:01:50,140 So the rest is the same. 37 00:01:50,140 --> 00:01:51,290 And here it's of course 38 00:01:53,310 --> 00:01:58,310 UNCAUGHT EXCEPTION! 39 00:01:58,320 --> 00:02:01,810 Now I could refactor this here into a nice function, 40 00:02:01,810 --> 00:02:05,020 but let's just keep it like this, all right? 41 00:02:05,020 --> 00:02:07,123 Okay, so let's now rerun this. 42 00:02:08,330 --> 00:02:11,090 And so let's take a look at what we have here. 43 00:02:11,090 --> 00:02:13,700 And indeed, we now see UNCAUGHT EXCEPTION! 44 00:02:13,700 --> 00:02:14,780 Shutting down. 45 00:02:14,780 --> 00:02:15,750 All right? 46 00:02:15,750 --> 00:02:18,770 And actually this again prints the entire stack 47 00:02:18,770 --> 00:02:21,400 to the console, but I don't really want that. 48 00:02:21,400 --> 00:02:22,660 I don't like that. 49 00:02:22,660 --> 00:02:25,860 So let's just actually go back to what we had here. 50 00:02:25,860 --> 00:02:28,683 So err.name and then err.message. 51 00:02:30,890 --> 00:02:32,610 Okay, and so now we have the ReferenceError 52 00:02:32,610 --> 00:02:36,290 that x is not defined, okay? 53 00:02:36,290 --> 00:02:38,520 And let's just put the same here. 54 00:02:38,520 --> 00:02:39,983 So just like it was before. 55 00:02:40,950 --> 00:02:41,783 All right. 56 00:02:41,783 --> 00:02:43,070 And that's actually all there is 57 00:02:43,070 --> 00:02:45,370 to catching uncaught exceptions. 58 00:02:45,370 --> 00:02:48,180 Now while here in the unhandled rejection, 59 00:02:48,180 --> 00:02:51,230 crashing the application like we did here is optional, 60 00:02:51,230 --> 00:02:53,630 when there is an uncaught exception, 61 00:02:53,630 --> 00:02:57,150 we really, really need to crash our application 62 00:02:57,150 --> 00:02:59,970 because after there was an uncaught exception, 63 00:02:59,970 --> 00:03:01,610 the entire node process is 64 00:03:01,610 --> 00:03:04,370 in a so-called unclean state, all right? 65 00:03:04,370 --> 00:03:07,770 And so to fix that, the process need to terminate 66 00:03:07,770 --> 00:03:09,940 and then to be restarted, all right? 67 00:03:09,940 --> 00:03:11,330 And again, in production, 68 00:03:11,330 --> 00:03:13,460 we should then have a tool in place 69 00:03:13,460 --> 00:03:16,640 which will restart the application after crashing. 70 00:03:16,640 --> 00:03:19,270 And many hosting services already do that 71 00:03:19,270 --> 00:03:20,860 out of the box, all right? 72 00:03:20,860 --> 00:03:23,170 So, completely automatically without 73 00:03:23,170 --> 00:03:24,980 us having to do anything. 74 00:03:24,980 --> 00:03:27,820 Now, in Node.js, it's not really a good practice 75 00:03:27,820 --> 00:03:31,580 to just blindly rely on these two error handlers 76 00:03:31,580 --> 00:03:34,170 that we just implemented here, okay? 77 00:03:34,170 --> 00:03:36,470 So ideally errors should really be handled 78 00:03:36,470 --> 00:03:38,120 right where they occur. 79 00:03:38,120 --> 00:03:42,150 So for example, in the problem connecting to the database, 80 00:03:42,150 --> 00:03:44,660 we should of course add a catch handler there 81 00:03:44,660 --> 00:03:46,480 and not just simply rely on the 82 00:03:46,480 --> 00:03:50,160 unhandled rejection callback that we have here, okay? 83 00:03:50,160 --> 00:03:53,600 And some people even say that we shouldn't use these at all, 84 00:03:53,600 --> 00:03:54,770 but I disagree with that. 85 00:03:54,770 --> 00:03:58,090 I think that as a safety net, let's say, 86 00:03:58,090 --> 00:04:02,470 they can be very useful and play a part in our application. 87 00:04:02,470 --> 00:04:04,020 Now actually this handler here 88 00:04:04,020 --> 00:04:07,300 should be at the very top of our code, okay? 89 00:04:07,300 --> 00:04:11,280 Or at least before any other code is really executed. 90 00:04:11,280 --> 00:04:14,980 Because watch what happens if I move this line of code here 91 00:04:14,980 --> 00:04:16,513 before this handler. 92 00:04:17,350 --> 00:04:19,593 So if I put it here, for example, 93 00:04:21,140 --> 00:04:23,070 and then give it a save, 94 00:04:23,070 --> 00:04:24,680 then you actually see that our handler 95 00:04:24,680 --> 00:04:29,410 does not catch this exception, so this error here, right? 96 00:04:29,410 --> 00:04:31,830 And so that's because only here at the end 97 00:04:31,830 --> 00:04:35,010 we actually start listening for an uncaught exception. 98 00:04:35,010 --> 00:04:37,580 But in this case here, the uncaught exception 99 00:04:37,580 --> 00:04:40,380 happens before we even listen to that event. 100 00:04:40,380 --> 00:04:44,630 And so therefore, we have no way of catching it, right? 101 00:04:44,630 --> 00:04:48,920 And so we should ideally put it here, right at the top, 102 00:04:48,920 --> 00:04:51,030 again before any other code executes. 103 00:04:51,030 --> 00:04:53,423 Especially the one in our application. 104 00:04:54,580 --> 00:04:57,760 So let's put it actually right here. 105 00:04:57,760 --> 00:04:59,550 Now the problem here will be 106 00:04:59,550 --> 00:05:02,820 that the server is not defined at this point. 107 00:05:02,820 --> 00:05:04,160 But that's not a problem, 108 00:05:04,160 --> 00:05:06,180 because actually we don't need the server here 109 00:05:06,180 --> 00:05:08,060 at all, all right? 110 00:05:08,060 --> 00:05:09,480 And that's because these errors, 111 00:05:09,480 --> 00:05:11,270 so these uncaught exceptions, 112 00:05:11,270 --> 00:05:13,670 they are not gonna happen asynchronously. 113 00:05:13,670 --> 00:05:15,630 So they are not gonna have anything to do 114 00:05:15,630 --> 00:05:17,660 with the server actually. 115 00:05:17,660 --> 00:05:19,360 So we don't need this here at all. 116 00:05:20,470 --> 00:05:22,250 We can just save it here, 117 00:05:22,250 --> 00:05:25,480 and so now we have it before we actually require 118 00:05:25,480 --> 00:05:26,890 our main application. 119 00:05:26,890 --> 00:05:28,663 And so if we now have an error, 120 00:05:29,940 --> 00:05:31,850 let's try it first here, 121 00:05:31,850 --> 00:05:33,500 so you see that now we're back 122 00:05:33,500 --> 00:05:36,710 to actually catching it in our error handler. 123 00:05:36,710 --> 00:05:41,333 But if we now had this code, for example inside of app.js, 124 00:05:42,350 --> 00:05:45,810 let's say, it doesn't really matter, 125 00:05:45,810 --> 00:05:47,410 let's just say it's here, 126 00:05:47,410 --> 00:05:50,260 and if we now run this, well then you see 127 00:05:50,260 --> 00:05:52,530 that we're still catching that exception 128 00:05:52,530 --> 00:05:56,290 in our error handler, which before would not be the case. 129 00:05:56,290 --> 00:05:57,180 All right? 130 00:05:57,180 --> 00:05:59,590 And now just for an experiment, 131 00:05:59,590 --> 00:06:03,120 what do you think if we put this code 132 00:06:03,120 --> 00:06:06,100 right here in this middleware function? 133 00:06:06,100 --> 00:06:07,690 What do you think is gonna happen 134 00:06:07,690 --> 00:06:09,510 when we save this file now? 135 00:06:09,510 --> 00:06:12,200 So x is still not defined anywhere, 136 00:06:12,200 --> 00:06:13,840 but let's take a look at what happens 137 00:06:13,840 --> 00:06:15,373 when we now run this code. 138 00:06:16,980 --> 00:06:19,510 And so now we actually have no error. 139 00:06:19,510 --> 00:06:21,300 Or actually we do, but that's only 140 00:06:21,300 --> 00:06:24,130 because of our unhandled rejection, 141 00:06:24,130 --> 00:06:26,020 which is due to the fact 142 00:06:26,020 --> 00:06:27,920 that our password here is still wrong. 143 00:06:29,290 --> 00:06:32,170 So if we save that and now save it again, 144 00:06:32,170 --> 00:06:34,560 you should see no error at all. 145 00:06:34,560 --> 00:06:35,730 And indeed, we don't. 146 00:06:35,730 --> 00:06:36,953 And why is that? 147 00:06:37,830 --> 00:06:40,940 Well, it's because this middleware function here of course 148 00:06:40,940 --> 00:06:42,450 is only called as soon 149 00:06:42,450 --> 00:06:45,220 as there actually is a request, right? 150 00:06:45,220 --> 00:06:48,113 And so let's see what happens when we do a request. 151 00:06:50,760 --> 00:06:54,180 And so let's do a Get All Tours request. 152 00:06:54,180 --> 00:06:55,720 And let's wait for it. 153 00:06:55,720 --> 00:06:58,980 And, here we get a "Something went very wrong!" 154 00:06:58,980 --> 00:07:01,420 error message with the 500, 155 00:07:01,420 --> 00:07:03,560 and that's also because we are still 156 00:07:03,560 --> 00:07:05,820 in production mode, okay? 157 00:07:05,820 --> 00:07:08,990 But anyway, getting this message here, remember, 158 00:07:08,990 --> 00:07:12,120 means that we have a nonoperational error here. 159 00:07:12,120 --> 00:07:15,630 So basically an error that we did not create ourselves. 160 00:07:15,630 --> 00:07:19,580 And so, right this, we now enter here 161 00:07:19,580 --> 00:07:24,380 in our errorController, we go right here, right? 162 00:07:24,380 --> 00:07:28,780 So into this else branch here in the sendErrorProd function. 163 00:07:28,780 --> 00:07:30,380 And actually you see the error 164 00:07:30,380 --> 00:07:32,970 down here in the console as well, okay? 165 00:07:32,970 --> 00:07:35,600 And so that's what happens when there is an error 166 00:07:35,600 --> 00:07:39,430 inside of any Express middleware, right? 167 00:07:39,430 --> 00:07:41,370 So Express, when there is an error, 168 00:07:41,370 --> 00:07:44,480 will automatically go to the error-handling middleware 169 00:07:44,480 --> 00:07:46,330 with that error, okay? 170 00:07:46,330 --> 00:07:48,100 And so that's why when we get an error 171 00:07:48,100 --> 00:07:50,410 here in any of our middleware function, 172 00:07:50,410 --> 00:07:55,240 it will immediately go here into this handler, okay? 173 00:07:55,240 --> 00:07:56,520 And since we're in production, 174 00:07:56,520 --> 00:07:58,730 it will enter this block here, 175 00:07:58,730 --> 00:08:00,994 but since it's not a CastError, 176 00:08:00,994 --> 00:08:03,700 and not this error, and not a ValidationError, 177 00:08:03,700 --> 00:08:06,830 then as soon as the error is actually sent, 178 00:08:06,830 --> 00:08:09,640 right here, we then enter this block. 179 00:08:09,640 --> 00:08:14,640 And again, that's why we send this generic error, all right? 180 00:08:15,235 --> 00:08:17,500 Let's now actually exit this mode here 181 00:08:17,500 --> 00:08:20,053 and go back to our normal npm start. 182 00:08:22,310 --> 00:08:26,130 And so right now, our error will be sent like this, right? 183 00:08:26,130 --> 00:08:29,440 So send development error will give us all the details 184 00:08:29,440 --> 00:08:31,773 about the error that is happening. 185 00:08:33,610 --> 00:08:38,490 And so now indeed we get ReferenceError: x is not defined. 186 00:08:38,490 --> 00:08:39,323 Okay? 187 00:08:39,323 --> 00:08:41,533 So in app.js, line 21. 188 00:08:42,480 --> 00:08:46,300 And so, line 21 is where it is, 189 00:08:46,300 --> 00:08:47,520 but let's get rid of it. 190 00:08:47,520 --> 00:08:49,760 I just wanted to show it to you. 191 00:08:49,760 --> 00:08:51,350 Okay? 192 00:08:51,350 --> 00:08:53,770 Anyway, with this, we actually close 193 00:08:53,770 --> 00:08:55,620 our error handling section. 194 00:08:55,620 --> 00:08:58,830 And there could be an entire course on error handling 195 00:08:58,830 --> 00:09:01,940 with Node and Express, because it really is 196 00:09:01,940 --> 00:09:03,830 an insanely complex topic. 197 00:09:03,830 --> 00:09:06,470 But, in this section, you learn the essentials 198 00:09:06,470 --> 00:09:08,830 that you need to know in order to really get started 199 00:09:08,830 --> 00:09:10,943 building amazing applications.