﻿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,330
‫in our express application

6
00:00:16,330 --> 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,073
‫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,050
‫But now, you might ask, what about the synchronous code?

169
00:08:38,050 --> 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.

