Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,120 --> 00:00:03,120
In this video, let's talk about something
2
00:00:03,120 --> 00:00:06,770
that we have in node.js called unhandled rejections
3
00:00:06,770 --> 00:00:09,543
and then learn how we can actually handle them.
4
00:00:10,970 --> 00:00:14,400
So at this point, we have successfully handled errors
5
00:00:14,400 --> 00:00:16,329
in our express application
6
00:00:16,329 --> 00:00:19,970
by passing operational asynchronous errors down
7
00:00:19,970 --> 00:00:22,410
into a global error handling middleware.
8
00:00:22,410 --> 00:00:26,200
This, then sends relevant error messages back to the client
9
00:00:26,200 --> 00:00:30,510
depending on the type of error that occurred, right?
10
00:00:30,510 --> 00:00:34,730
However, there might also occur errors outside of express
11
00:00:34,730 --> 00:00:38,520
and a good example for that in our current application
12
00:00:38,520 --> 00:00:40,810
is the mongodb database connection.
13
00:00:40,810 --> 00:00:43,700
So imagine that the database is down for some reason
14
00:00:43,700 --> 00:00:46,000
or for some reason, we cannot log in.
15
00:00:46,000 --> 00:00:47,920
And in that case, there are errors
16
00:00:47,920 --> 00:00:49,610
that we have to handle as well.
17
00:00:49,610 --> 00:00:52,800
But they didn't occur inside of our express application
18
00:00:52,800 --> 00:00:55,810
and so, of course, our error handler that we implemented
19
00:00:55,810 --> 00:00:58,560
will not catch this errors, right?
20
00:00:58,560 --> 00:01:01,790
And so just to test what happens, let's go ahead
21
00:01:01,790 --> 00:01:05,110
and change our mongodb password, okay?
22
00:01:05,110 --> 00:01:06,960
Because that way, we're not gonna be able
23
00:01:06,960 --> 00:01:10,180
to connect to the database, right?
24
00:01:10,180 --> 00:01:13,110
And so we should then get some kind of error,
25
00:01:13,110 --> 00:01:15,510
and so let's go here to our server file
26
00:01:15,510 --> 00:01:18,633
and save it in order to reload our server,
27
00:01:20,710 --> 00:01:23,040
let's increase it here, and indeed,
28
00:01:23,040 --> 00:01:26,120
here we have an unhandled promise rejection.
29
00:01:26,120 --> 00:01:29,510
And so that is actually the topic of this video.
30
00:01:29,510 --> 00:01:33,600
So an unhandled promise rejection means that somewhere
31
00:01:33,600 --> 00:01:37,140
in our code, there is a promise that got rejected.
32
00:01:37,140 --> 00:01:41,270
But that rejection has not been handled anywhere, all right?
33
00:01:41,270 --> 00:01:44,920
And down here, you also see a deprecation warning
34
00:01:44,920 --> 00:01:48,008
which says that in the future unhandled rejections
35
00:01:48,008 --> 00:01:51,710
will simply exit the node program that's running,
36
00:01:51,710 --> 00:01:54,940
which may not always be what you want, okay?
37
00:01:54,940 --> 00:01:57,450
So let's fix this problem and get rid
38
00:01:57,450 --> 00:02:00,000
of this unhandled promise rejection.
39
00:02:00,000 --> 00:02:01,910
Now, in this simple example here,
40
00:02:01,910 --> 00:02:03,270
it would be actually quite easy
41
00:02:03,270 --> 00:02:05,770
to handle that rejection, right?
42
00:02:05,770 --> 00:02:08,060
All we'll have to do would to come here
43
00:02:08,060 --> 00:02:11,550
to this piece of code where our connection is actually done
44
00:02:11,550 --> 00:02:14,100
and then, add a catch handler there, right?
45
00:02:14,100 --> 00:02:16,580
So a bit like this, and then in here,
46
00:02:16,580 --> 00:02:18,640
we could handle that rejection
47
00:02:18,640 --> 00:02:20,970
and would then no longer get this error.
48
00:02:20,970 --> 00:02:22,820
Let me just quickly show that to you.
49
00:02:29,905 --> 00:02:31,960
So try it again.
50
00:02:31,960 --> 00:02:35,630
And so now, you get error which is of course,
51
00:02:35,630 --> 00:02:37,950
the result of this log here,
52
00:02:37,950 --> 00:02:41,010
but of course, we get no unhandled promise rejection,
53
00:02:41,010 --> 00:02:45,060
again, because we actually handled it here, all right?
54
00:02:45,060 --> 00:02:48,580
So this would work, of course, but I really want to show you
55
00:02:48,580 --> 00:02:51,720
how to globally handle unhandled rejected promises,
56
00:02:51,720 --> 00:02:54,680
because in a bigger application, it can become a bit
57
00:02:54,680 --> 00:02:57,860
more difficult to always keep track of all the promises
58
00:02:57,860 --> 00:03:00,590
that might become rejected at some point, okay?
59
00:03:00,590 --> 00:03:03,280
And so at some point, you might have some unhandled
60
00:03:03,280 --> 00:03:06,690
promise rejection somewhere and so let me show you
61
00:03:06,690 --> 00:03:09,860
how to deal with that globally basically.
62
00:03:09,860 --> 00:03:14,070
And so let's now learn how to handle unhandled rejections
63
00:03:14,070 --> 00:03:16,160
and we're gonna do that right here.
64
00:03:16,160 --> 00:03:19,530
And so remember how in one of the first section
65
00:03:19,530 --> 00:03:21,900
of the course, we talked about events
66
00:03:21,900 --> 00:03:24,080
and event listeners, right?
67
00:03:24,080 --> 00:03:28,010
And so now, it's time to actually use that knowledge.
68
00:03:28,010 --> 00:03:30,940
So each time that there is an unhandled rejection
69
00:03:30,940 --> 00:03:34,180
somewhere in our application, the process object
70
00:03:34,180 --> 00:03:37,470
will emit an object called unhandled rejection
71
00:03:37,470 --> 00:03:41,223
and so we can subscribe to that event just like this.
72
00:03:42,250 --> 00:03:46,903
So process.on, remember, and then the name of the event,
73
00:03:48,004 --> 00:03:52,053
unhandled rejection,
74
00:03:52,930 --> 00:03:55,240
and then the callback function here
75
00:03:55,240 --> 00:03:59,369
receives an error, and so let's actually go ahead
76
00:03:59,369 --> 00:04:02,793
and log the error to the console.
77
00:04:03,780 --> 00:04:08,653
So let's use err.name and err.message.
78
00:04:09,620 --> 00:04:11,640
So these are kind of some defaults
79
00:04:12,500 --> 00:04:16,072
that we have on all errors in node.js, all right?
80
00:04:17,570 --> 00:04:20,930
Okay, and after saving, we already, down here
81
00:04:20,930 --> 00:04:24,410
get the name of the error and also the error message.
82
00:04:24,410 --> 00:04:27,940
So bad authentication which is because, of course,
83
00:04:27,940 --> 00:04:29,490
we have the wrong password.
84
00:04:29,490 --> 00:04:32,360
And so right now, the unhandled promise rejection
85
00:04:32,360 --> 00:04:33,960
is now actually handled.
86
00:04:33,960 --> 00:04:37,430
And of course, not just the one from this failed connection
87
00:04:37,430 --> 00:04:40,410
but any other promise rejection that we might not catch
88
00:04:40,410 --> 00:04:44,260
somewhere in the application is handled here in this final,
89
00:04:44,260 --> 00:04:46,880
let's call it safety net, all right?
90
00:04:46,880 --> 00:04:49,890
So we always have to assume that we as programmers
91
00:04:49,890 --> 00:04:51,410
are gonna make errors.
92
00:04:51,410 --> 00:04:54,740
And so it's always best to have a central place like this
93
00:04:54,740 --> 00:04:56,560
to handle all promise rejections
94
00:04:56,560 --> 00:04:59,132
like a last safety net, all right?
95
00:04:59,132 --> 00:05:01,800
Now, if we really have like some problem
96
00:05:01,800 --> 00:05:04,890
with the database connection, like we have in this example,
97
00:05:04,890 --> 00:05:07,840
then our application is not gonna work at all.
98
00:05:07,840 --> 00:05:09,760
And so all we can really do here
99
00:05:09,760 --> 00:05:12,820
is to shut down our application, all right?
100
00:05:12,820 --> 00:05:17,053
So to shutdown the application, we use process.exit.
101
00:05:18,140 --> 00:05:20,420
And we actually already used that before
102
00:05:20,420 --> 00:05:22,850
in that script where we imported all the data
103
00:05:22,850 --> 00:05:27,080
into the database from the JSON file, remember?
104
00:05:27,080 --> 00:05:29,660
So process.exit and then in here,
105
00:05:29,660 --> 00:05:31,810
we can actually pass a code.
106
00:05:31,810 --> 00:05:34,140
And the code zero stands for a success
107
00:05:34,140 --> 00:05:36,800
and one stands for uncaught exception.
108
00:05:36,800 --> 00:05:40,230
And so that's the one that's usually used here, all right?
109
00:05:40,230 --> 00:05:43,400
So usually, you will always see it like this.
110
00:05:43,400 --> 00:05:46,970
And let's just add like a log here, console.log
111
00:05:50,293 --> 00:05:51,973
unhandler the rejection,
112
00:05:56,020 --> 00:05:57,560
something like this.
113
00:05:57,560 --> 00:05:59,860
So you see, I really like this, this one here.
114
00:06:02,910 --> 00:06:04,650
Just letting this are node...
115
00:06:04,650 --> 00:06:06,730
Not really user but our log
116
00:06:06,730 --> 00:06:09,320
that we're shutting down, all right?
117
00:06:09,320 --> 00:06:12,330
And so now, you see that the app actually crashed.
118
00:06:12,330 --> 00:06:16,515
And so that's because of this process.exit here, all right?
119
00:06:16,515 --> 00:06:18,860
Now, there is just one problem with the way
120
00:06:18,860 --> 00:06:20,480
we implemented it right now
121
00:06:20,480 --> 00:06:23,430
and that is, that the way we implement it here
122
00:06:23,430 --> 00:06:26,990
so just process.exit is a very abrupt way
123
00:06:26,990 --> 00:06:30,420
of ending the program because this will just immediately
124
00:06:30,420 --> 00:06:34,030
abort all the requests that are currently still running
125
00:06:34,030 --> 00:06:38,300
or pending and so that might not be a good idea, okay?
126
00:06:38,300 --> 00:06:41,550
And so usually, what we do is to shutdown gracefully
127
00:06:41,550 --> 00:06:44,210
where we first close the server and only then,
128
00:06:44,210 --> 00:06:47,140
we shut down the application, okay?
129
00:06:47,140 --> 00:06:47,973
So let's...
130
00:06:47,973 --> 00:06:51,440
Before we do that, we need to save the server here
131
00:06:51,440 --> 00:06:55,670
basically to a variable, okay?
132
00:06:55,670 --> 00:06:59,650
And so the result of calling app.listen is a server
133
00:06:59,650 --> 00:07:04,650
and to now, on that server, we can then say server.close
134
00:07:05,810 --> 00:07:08,400
which will, as the name says, close the server
135
00:07:08,400 --> 00:07:10,490
and then after that's done,
136
00:07:10,490 --> 00:07:14,810
it will run this callback function that we passed into it
137
00:07:14,810 --> 00:07:16,130
and so it's only here,
138
00:07:16,130 --> 00:07:19,310
where we then shut down the server, okay?
139
00:07:19,310 --> 00:07:22,240
And so by doing this, by doing server.close,
140
00:07:22,240 --> 00:07:25,630
we give the server, basically time to finish all the request
141
00:07:25,630 --> 00:07:28,890
that are still pending or being handled at the time,
142
00:07:28,890 --> 00:07:31,180
and only after that, the server is then basically
143
00:07:31,180 --> 00:07:32,910
killed, all right?
144
00:07:32,910 --> 00:07:34,620
So when we give it a safe, it's not gonna look
145
00:07:34,620 --> 00:07:37,020
exactly the same because, (laughs) yeah,
146
00:07:37,020 --> 00:07:39,880
we're like the only ones that really accessing
147
00:07:39,880 --> 00:07:42,850
this application but in the real world scenario,
148
00:07:42,850 --> 00:07:45,960
we should always do it like this, okay?
149
00:07:45,960 --> 00:07:48,200
And of course, that's not really ideal
150
00:07:48,200 --> 00:07:50,520
that the application crashed, right?
151
00:07:50,520 --> 00:07:53,120
Because right now, of course, the app is not running,
152
00:07:53,120 --> 00:07:55,448
it's not working at all, right?
153
00:07:55,448 --> 00:07:59,570
And so usually, in a production app on a web server,
154
00:07:59,570 --> 00:08:01,690
we will usually have some tool in place
155
00:08:01,690 --> 00:08:05,100
that restarts the application right after it crashes,
156
00:08:05,100 --> 00:08:08,120
or also some of the platforms that host node.js
157
00:08:08,120 --> 00:08:11,164
will automatically do that on their own, okay?
158
00:08:11,164 --> 00:08:13,920
Because, of course, we don't wanna leave the application
159
00:08:13,920 --> 00:08:15,590
hanging like this forever.
160
00:08:15,590 --> 00:08:18,420
So that's not useful either, all right?
161
00:08:18,420 --> 00:08:20,410
And so basically, this is how you handle
162
00:08:20,410 --> 00:08:22,590
unhandled rejected promises.
163
00:08:22,590 --> 00:08:25,130
So again, basically, we are listening
164
00:08:25,130 --> 00:08:27,930
to this unhandled rejection event,
165
00:08:27,930 --> 00:08:30,100
which then allows us to handle all the errors
166
00:08:30,100 --> 00:08:32,280
that occur in asynchronous code
167
00:08:32,280 --> 00:08:34,470
which were not previously handled.
168
00:08:34,470 --> 00:08:38,049
But now, you might ask, what about the synchronous code?
169
00:08:38,049 --> 00:08:40,110
Where are we gonna handle that?
170
00:08:40,110 --> 00:08:43,020
And the answer to that lies, as you can imagine,
171
00:08:43,020 --> 00:08:44,523
in the next video.
14026
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.