﻿1
00:00:01,210 --> 00:00:04,370
‫In this lecture, let's implement a better way

2
00:00:04,370 --> 00:00:07,853
‫of catching errors in all our async functions.

3
00:00:09,310 --> 00:00:12,180
‫So right now, in all our async functions,

4
00:00:12,180 --> 00:00:15,750
‫we have these try catch blocks, right?

5
00:00:15,750 --> 00:00:20,430
‫So, remember how we added to all of these handle functions

6
00:00:20,430 --> 00:00:23,930
‫this try and then this catch block, okay?

7
00:00:23,930 --> 00:00:26,430
‫And so all of them have this

8
00:00:26,430 --> 00:00:28,900
‫because all of them are async functions

9
00:00:28,900 --> 00:00:31,930
‫and that's how we usually catch the errors

10
00:00:31,930 --> 00:00:33,863
‫inside of an asynchronous function.

11
00:00:34,800 --> 00:00:37,100
‫So using a try catch block.

12
00:00:37,100 --> 00:00:41,170
‫Now that really makes our code look messy and unfocused

13
00:00:41,170 --> 00:00:44,740
‫so the goal of this createTour method here, for example,

14
00:00:44,740 --> 00:00:46,560
‫is to just run this code.

15
00:00:46,560 --> 00:00:48,500
‫We actually do not want to mess around

16
00:00:48,500 --> 00:00:49,934
‫with error handling here,

17
00:00:49,934 --> 00:00:53,450
‫so right now we have these two extra blocks,

18
00:00:53,450 --> 00:00:55,690
‫try and catch, and with that comes

19
00:00:55,690 --> 00:00:57,900
‫this extra indentation here

20
00:00:57,900 --> 00:01:01,730
‫and so again, this really makes our code look not clean.

21
00:01:01,730 --> 00:01:03,550
‫It's really not focused.

22
00:01:03,550 --> 00:01:05,940
‫Also, we have a lot of duplicate code here

23
00:01:05,940 --> 00:01:07,830
‫because in each of these handlers,

24
00:01:07,830 --> 00:01:10,310
‫we have quite a similar catch block.

25
00:01:10,310 --> 00:01:12,250
‫So in all of this, all we're doing is

26
00:01:12,250 --> 00:01:14,690
‫really to send this response.

27
00:01:14,690 --> 00:01:17,490
‫And that response would actually not even be sent here

28
00:01:17,490 --> 00:01:20,900
‫but instead in our global error handling middleware,

29
00:01:20,900 --> 00:01:23,010
‫remember, but that's another topic.

30
00:01:23,010 --> 00:01:24,910
‫For now, what I'm trying to focus here

31
00:01:24,910 --> 00:01:27,170
‫is that these try catch blocks inside

32
00:01:27,170 --> 00:01:30,840
‫of each of our async functions are not ideal

33
00:01:30,840 --> 00:01:34,010
‫and so let's now try to fix that.

34
00:01:34,010 --> 00:01:37,100
‫And the solution is to basically take the try catch block

35
00:01:37,100 --> 00:01:39,890
‫out of here and put it on a higher level

36
00:01:39,890 --> 00:01:41,450
‫in another function.

37
00:01:41,450 --> 00:01:43,000
‫So basically what we're gonna do

38
00:01:43,000 --> 00:01:44,470
‫is to create a function,

39
00:01:44,470 --> 00:01:49,326
‫and then wrap this async function into that function.

40
00:01:49,326 --> 00:01:50,630
‫All right?

41
00:01:50,630 --> 00:01:53,333
‫And so let me call that one catchAsync.

42
00:01:56,960 --> 00:02:00,290
‫So catchAsync, and I'm calling it this way

43
00:02:00,290 --> 00:02:02,380
‫because the goal of this function

44
00:02:02,380 --> 00:02:05,410
‫is to simply catch our asynchronous errors.

45
00:02:05,410 --> 00:02:06,613
‫So simple, right?

46
00:02:07,500 --> 00:02:09,840
‫So into this catchAsync function,

47
00:02:09,840 --> 00:02:13,660
‫we will pass in a function, okay?

48
00:02:13,660 --> 00:02:16,820
‫And remember, the function that we're gonna pass in

49
00:02:16,820 --> 00:02:19,030
‫is basically this one.

50
00:02:19,030 --> 00:02:21,678
‫So now that we're working with this example

51
00:02:21,678 --> 00:02:25,420
‫the function that we will pass into the catchAsync

52
00:02:25,420 --> 00:02:27,840
‫is this function because this is where we want

53
00:02:27,840 --> 00:02:30,033
‫to catch the asynchronous errors.

54
00:02:31,030 --> 00:02:32,563
‫So let's actually do that.

55
00:02:34,090 --> 00:02:39,090
‫So fn, and then wrap that entire function into there.

56
00:02:40,950 --> 00:02:43,340
‫So next up, what we then have to do

57
00:02:43,340 --> 00:02:45,440
‫is to actually call this function in here.

58
00:02:46,670 --> 00:02:49,640
‫So call it, and this function should receive

59
00:02:49,640 --> 00:02:53,810
‫request, response, and in fact, also next.

60
00:02:53,810 --> 00:02:57,440
‫So this one here should actually also have next

61
00:02:57,440 --> 00:02:58,860
‫and all the others, as well,

62
00:02:58,860 --> 00:03:01,260
‫because remember, we need the next function

63
00:03:01,260 --> 00:03:03,540
‫in order to pass the error into it

64
00:03:03,540 --> 00:03:05,660
‫so that that error can then be handled

65
00:03:05,660 --> 00:03:08,470
‫in the global error handling middleware.

66
00:03:08,470 --> 00:03:10,360
‫So all of these functions are gonna need

67
00:03:10,360 --> 00:03:12,063
‫request, response, and next.

68
00:03:12,950 --> 00:03:14,540
‫But let's leave that for later.

69
00:03:14,540 --> 00:03:17,090
‫For now, let's really focus on our catchAsync here.

70
00:03:19,180 --> 00:03:22,120
‫So this function here that we passed into async,

71
00:03:22,120 --> 00:03:24,290
‫which is now called fn up here,

72
00:03:24,290 --> 00:03:26,040
‫is an asynchronous function.

73
00:03:26,040 --> 00:03:28,080
‫And remember that asynchronous functions

74
00:03:28,080 --> 00:03:30,490
‫return promises, right?

75
00:03:30,490 --> 00:03:33,500
‫And when there is an error inside of an async function,

76
00:03:33,500 --> 00:03:37,310
‫that basically means that the promise gets rejected.

77
00:03:37,310 --> 00:03:40,160
‫And so up here, where we actually call that function,

78
00:03:40,160 --> 00:03:41,893
‫we can then catch that error.

79
00:03:43,790 --> 00:03:46,040
‫So we catch it here, instead of catching it

80
00:03:46,040 --> 00:03:48,590
‫in the try catch block.

81
00:03:48,590 --> 00:03:53,590
‫So catch, and error, and then next, and pass the error.

82
00:03:57,040 --> 00:03:58,160
‫And we can simplify this,

83
00:03:58,160 --> 00:04:01,810
‫but for now let's remove the try catch block here,

84
00:04:01,810 --> 00:04:05,103
‫and so simply focus on this piece.

85
00:04:07,580 --> 00:04:08,920
‫So this is all we want

86
00:04:08,920 --> 00:04:12,110
‫and we no longer need the try catch block,

87
00:04:12,110 --> 00:04:15,660
‫again, because that catch is now basically transferred

88
00:04:15,660 --> 00:04:17,113
‫to here, to this line.

89
00:04:18,500 --> 00:04:20,350
‫It's no longer a catch block,

90
00:04:20,350 --> 00:04:22,560
‫because in here it's just easier to use

91
00:04:22,560 --> 00:04:26,060
‫the promise that the fn function returns.

92
00:04:26,060 --> 00:04:29,640
‫So again, this fn function is this function,

93
00:04:29,640 --> 00:04:32,270
‫so the one that we passed into catchAsync,

94
00:04:32,270 --> 00:04:34,650
‫and so that is gonna return a promise.

95
00:04:34,650 --> 00:04:37,100
‫And actually, I noticed here that this, of course,

96
00:04:37,100 --> 00:04:40,110
‫should be called catchAsync, all right?

97
00:04:40,110 --> 00:04:41,800
‫And then so that function that we passed

98
00:04:41,800 --> 00:04:45,447
‫into catchAsync, this one is of course then fn.

99
00:04:45,447 --> 00:04:46,280
‫All right?

100
00:04:46,280 --> 00:04:48,980
‫So the argument that we passed in there.

101
00:04:48,980 --> 00:04:51,590
‫Now there are actually two big problems

102
00:04:51,590 --> 00:04:54,180
‫with the way that this is implemented right now

103
00:04:54,180 --> 00:04:57,240
‫and so this way, it wouldn't really work at all.

104
00:04:57,240 --> 00:04:59,340
‫So first one, this function call here

105
00:04:59,340 --> 00:05:03,213
‫has no way of knowing request, response, and next.

106
00:05:04,300 --> 00:05:07,460
‫We did not pass them into catchAsync here,

107
00:05:07,460 --> 00:05:09,300
‫and so really there's no way

108
00:05:09,300 --> 00:05:12,693
‫for the function to know the values of these parameters.

109
00:05:13,658 --> 00:05:15,610
‫And second is that right here

110
00:05:15,610 --> 00:05:18,473
‫we are actually calling the async function.

111
00:05:20,290 --> 00:05:22,290
‫And to see this a bit better, let's just

112
00:05:23,200 --> 00:05:24,873
‫get completely rid of this code.

113
00:05:26,370 --> 00:05:29,520
‫So here we have catchAsync and we are then calling it

114
00:05:29,520 --> 00:05:31,153
‫using the parentheses of course.

115
00:05:32,350 --> 00:05:34,900
‫And then inside of catchAsync we are also then

116
00:05:34,900 --> 00:05:37,760
‫right away calling the fn function,

117
00:05:37,760 --> 00:05:40,130
‫and that's not how it is supposed to work.

118
00:05:40,130 --> 00:05:43,060
‫So createTour here should really be a function

119
00:05:43,060 --> 00:05:45,840
‫but not the result of calling a function.

120
00:05:45,840 --> 00:05:47,810
‫But that's right now what's happening.

121
00:05:47,810 --> 00:05:49,940
‫So right now catchAsync is being called,

122
00:05:49,940 --> 00:05:54,310
‫which then calls this function here, okay?

123
00:05:54,310 --> 00:05:56,890
‫And so again, this function should not called,

124
00:05:56,890 --> 00:05:59,360
‫but instead it should sit here and wait

125
00:05:59,360 --> 00:06:01,460
‫until express calls it.

126
00:06:01,460 --> 00:06:03,310
‫And express will of course call it

127
00:06:03,310 --> 00:06:05,400
‫as soon as someone hits the route

128
00:06:05,400 --> 00:06:08,390
‫that needs this control function.

129
00:06:08,390 --> 00:06:11,980
‫And so the solution to that is to basically make

130
00:06:11,980 --> 00:06:15,030
‫the catchAsync function return another function

131
00:06:15,030 --> 00:06:18,060
‫which is then gonna be assigned to createTour

132
00:06:18,060 --> 00:06:19,640
‫and so that function can then

133
00:06:19,640 --> 00:06:21,483
‫later be called when necessary.

134
00:06:23,294 --> 00:06:24,394
‫So let's do that here.

135
00:06:25,590 --> 00:06:28,480
‫So let's return an anonymous function

136
00:06:28,480 --> 00:06:30,890
‫and so remember that this is the function

137
00:06:30,890 --> 00:06:32,900
‫that express is then gonna call.

138
00:06:32,900 --> 00:06:35,380
‫And so here is where we then specify

139
00:06:35,380 --> 00:06:38,423
‫request, response, and next.

140
00:06:41,120 --> 00:06:43,763
‫Actually missing the arrow here.

141
00:06:47,230 --> 00:06:48,480
‫And all right.

142
00:06:48,480 --> 00:06:49,890
‫And that's actually it.

143
00:06:49,890 --> 00:06:52,420
‫That's our catchAsync function.

144
00:06:52,420 --> 00:06:54,610
‫Just remember how I said that we could simplify it

145
00:06:54,610 --> 00:06:56,840
‫and that's just because, in JavaScript,

146
00:06:56,840 --> 00:06:59,110
‫we can simplify it like this

147
00:06:59,110 --> 00:07:01,777
‫so all we need to pass here is the function,

148
00:07:01,777 --> 00:07:04,020
‫and it will then be called automatically

149
00:07:04,020 --> 00:07:06,810
‫with the parameter that this callback receives.

150
00:07:06,810 --> 00:07:09,263
‫So it's the same as writing next.

151
00:07:11,500 --> 00:07:13,290
‫So let's recap here.

152
00:07:13,290 --> 00:07:16,490
‫So in order to get rid our try catch blocks,

153
00:07:16,490 --> 00:07:19,230
‫we simply wrapped our asynchronous function

154
00:07:19,230 --> 00:07:23,010
‫inside of the catchAsync function that we just created.

155
00:07:23,010 --> 00:07:26,160
‫This function will then return a new anonymous function,

156
00:07:26,160 --> 00:07:27,690
‫which is this one here,

157
00:07:27,690 --> 00:07:31,660
‫which will then be assigned to createTour.

158
00:07:31,660 --> 00:07:34,200
‫And so basically it is this function here

159
00:07:34,200 --> 00:07:36,940
‫that will get called as soon as a new tour

160
00:07:36,940 --> 00:07:40,010
‫should be created using the createTour handler.

161
00:07:40,010 --> 00:07:42,960
‫And so that's why it has the exact same signature here

162
00:07:42,960 --> 00:07:47,520
‫as this async function, with request, response, and next.

163
00:07:47,520 --> 00:07:49,740
‫Now what this function here will then do

164
00:07:49,740 --> 00:07:51,320
‫is that it will call the function

165
00:07:51,320 --> 00:07:53,440
‫that we passed in initially,

166
00:07:53,440 --> 00:07:54,990
‫so this one here,

167
00:07:54,990 --> 00:07:58,270
‫and it will then execute all the code that is in there.

168
00:07:58,270 --> 00:08:00,670
‫Now since it's an async function here,

169
00:08:00,670 --> 00:08:02,380
‫it will return a promise

170
00:08:02,380 --> 00:08:05,610
‫and therefore, in case there is an error in this promise

171
00:08:05,610 --> 00:08:08,400
‫or in other words, in case it gets rejected,

172
00:08:08,400 --> 00:08:11,090
‫we can then catch the error that happened

173
00:08:11,090 --> 00:08:15,193
‫using the catch method that is available on all promises.

174
00:08:16,560 --> 00:08:19,510
‫And in the end, it is this catch method here

175
00:08:19,510 --> 00:08:22,670
‫which will pass the error into the next function

176
00:08:22,670 --> 00:08:24,780
‫which will then make it so that our error

177
00:08:24,780 --> 00:08:27,943
‫ends up in our global error handling middleware.

178
00:08:28,890 --> 00:08:31,020
‫So this here, this line of code,

179
00:08:31,020 --> 00:08:33,510
‫is really where all the magic happens,

180
00:08:33,510 --> 00:08:35,440
‫and this is, in fact, what allows us

181
00:08:35,440 --> 00:08:38,893
‫to get rid of the catch block that we had previously.

182
00:08:39,770 --> 00:08:40,603
‫And a note:

183
00:08:40,603 --> 00:08:43,710
‫this is quite complicated to wrap your head around

184
00:08:43,710 --> 00:08:46,460
‫and in case that it's not 100% clear,

185
00:08:46,460 --> 00:08:48,943
‫don't worry, it's not all that important.

186
00:08:49,792 --> 00:08:53,010
‫This is really just about figuring out how exactly

187
00:08:53,010 --> 00:08:56,460
‫asynchronous code works behind the scenes in JavaScript.

188
00:08:56,460 --> 00:09:00,100
‫So it's not really so much about express or Node.js,

189
00:09:00,100 --> 00:09:04,060
‫this is more about how asynchronous code works.

190
00:09:04,060 --> 00:09:06,560
‫Now anyway, if we now create a new tour

191
00:09:06,560 --> 00:09:08,040
‫and some error happens,

192
00:09:08,040 --> 00:09:10,440
‫for example, from an invalid input,

193
00:09:10,440 --> 00:09:13,450
‫then that error should of course be catched here

194
00:09:13,450 --> 00:09:15,120
‫in this catch function,

195
00:09:15,120 --> 00:09:18,270
‫and will then be propagated to our error handling middleware

196
00:09:18,270 --> 00:09:21,870
‫and so that one will then send back the error response

197
00:09:21,870 --> 00:09:24,570
‫that we're expected to receive.

198
00:09:24,570 --> 00:09:26,973
‫And so let's now actually try that out.

199
00:09:28,080 --> 00:09:30,500
‫So create a new tour.

200
00:09:30,500 --> 00:09:32,030
‫Here we have the body,

201
00:09:32,030 --> 00:09:35,223
‫and let's now get rid of one of these required fields.

202
00:09:36,440 --> 00:09:37,273
‫All right.

203
00:09:37,273 --> 00:09:40,223
‫And so that should trigger an error, and so let's see.

204
00:09:41,220 --> 00:09:44,920
‫And indeed, our tour validation failed,

205
00:09:44,920 --> 00:09:46,910
‫which is exactly the error message

206
00:09:46,910 --> 00:09:49,090
‫that we were supposed to receive.

207
00:09:49,090 --> 00:09:53,220
‫Now here, you see this 500 Internal Server Error,

208
00:09:53,220 --> 00:09:55,710
‫which is simply due to the fact that right now

209
00:09:55,710 --> 00:09:57,500
‫the error that was propagated

210
00:09:57,500 --> 00:09:59,280
‫to the error handling middleware

211
00:09:59,280 --> 00:10:02,110
‫did not have any status code specified

212
00:10:02,110 --> 00:10:05,190
‫and so remember our default is 500

213
00:10:05,190 --> 00:10:08,310
‫and so that's the one that was then sent back.

214
00:10:08,310 --> 00:10:10,060
‫And of course, we need to fix that

215
00:10:10,060 --> 00:10:13,173
‫and we will do that in a later lecture in this course.

216
00:10:14,730 --> 00:10:17,030
‫For now, what matters here is that first,

217
00:10:17,030 --> 00:10:20,420
‫our catchAsync function works just as intended,

218
00:10:20,420 --> 00:10:23,700
‫and second, that the error was actually propagated,

219
00:10:23,700 --> 00:10:26,900
‫so it was catched by our global error handling middleware

220
00:10:26,900 --> 00:10:30,223
‫which then sent this response back to the client.

221
00:10:32,520 --> 00:10:35,360
‫Now let's actually go ahead and export

222
00:10:35,360 --> 00:10:38,010
‫this catch function into its own file.

223
00:10:38,010 --> 00:10:39,950
‫So I'm grabbing it from here

224
00:10:39,950 --> 00:10:42,200
‫and I will create just another file

225
00:10:42,200 --> 00:10:43,843
‫into our utilities folder.

226
00:10:47,060 --> 00:10:51,123
‫So catchAsync.js.

227
00:10:55,470 --> 00:11:00,470
‫And to here, module.exports should be just this.

228
00:11:04,650 --> 00:11:09,450
‫And so that should work just fine.

229
00:11:09,450 --> 00:11:11,340
‫Back in our tour controller we of course

230
00:11:11,340 --> 00:11:13,373
‫now need to import this function.

231
00:11:18,970 --> 00:11:21,840
‫And as usual, we need to go up one folder

232
00:11:22,840 --> 00:11:25,690
‫and then into our utilities folder

233
00:11:25,690 --> 00:11:27,733
‫and then catchAsync.

234
00:11:30,810 --> 00:11:32,840
‫All right, and now all we need to do

235
00:11:32,840 --> 00:11:36,080
‫is to get rid of all these catch blocks

236
00:11:36,080 --> 00:11:40,593
‫and wrap all the handlers into the catchAsync.

237
00:11:42,210 --> 00:11:43,793
‫So let's do that.

238
00:11:47,610 --> 00:11:52,610
‫First do the wrapping, and then getting rid of these blocks.

239
00:11:57,030 --> 00:12:00,220
‫Give it a save to reformat, and here we go.

240
00:12:00,220 --> 00:12:03,310
‫And now it's simply a process of repeating this

241
00:12:03,310 --> 00:12:06,821
‫until all of the tours, or,

242
00:12:06,821 --> 00:12:09,633
‫sorry, until all of the handlers are done.

243
00:12:13,070 --> 00:12:14,760
‫Okay, quick save.

244
00:12:14,760 --> 00:12:16,740
‫This one is already done.

245
00:12:16,740 --> 00:12:18,763
‫Next up is update.

246
00:12:26,920 --> 00:12:28,483
‫And only one more missing.

247
00:12:36,380 --> 00:12:37,870
‫Or actually, that's not true.

248
00:12:37,870 --> 00:12:40,403
‫Down there we have even more async functions.

249
00:12:52,530 --> 00:12:57,203
‫So we'll get rid of the catch and the try here.

250
00:12:59,150 --> 00:13:01,100
‫And I believe this one is the last one.

251
00:13:04,020 --> 00:13:05,483
‫And yeah, indeed it is.

252
00:13:12,390 --> 00:13:15,000
‫All right, now one other thing that we need to do

253
00:13:15,000 --> 00:13:19,040
‫is actually add next to all of them here as well.

254
00:13:19,040 --> 00:13:20,793
‫But of course, not in uppercase.

255
00:13:21,690 --> 00:13:22,960
‫Okay.

256
00:13:22,960 --> 00:13:25,480
‫And let me actually just select all of them here

257
00:13:28,170 --> 00:13:30,683
‫so that I only have to write it once.

258
00:13:33,140 --> 00:13:35,943
‫And so that added it to all of them.

259
00:13:38,390 --> 00:13:42,063
‫And so now I guess we're done with this part.

260
00:13:43,270 --> 00:13:46,310
‫Let's just very quickly test it again,

261
00:13:46,310 --> 00:13:48,733
‫not with this one, but here with,

262
00:13:49,950 --> 00:13:52,000
‫not with this one as well, so we're done.

263
00:13:55,330 --> 00:13:57,140
‫And I'm gonna try to get a tour

264
00:13:57,140 --> 00:14:01,870
‫but with an invalid ID, so let's see what happens here.

265
00:14:01,870 --> 00:14:04,250
‫And indeed, we get our error message

266
00:14:04,250 --> 00:14:06,950
‫and again with the 500 status code,

267
00:14:06,950 --> 00:14:08,640
‫which is not correct, remember,

268
00:14:08,640 --> 00:14:10,050
‫but we're gonna take care of that

269
00:14:10,050 --> 00:14:11,930
‫at a later point in time.

270
00:14:11,930 --> 00:14:15,130
‫So right now, let me show you

271
00:14:15,130 --> 00:14:19,920
‫that this here is where the 500 comes from

272
00:14:19,920 --> 00:14:22,200
‫because right now there's no status code

273
00:14:22,200 --> 00:14:24,310
‫inside of the error that we get

274
00:14:24,310 --> 00:14:27,940
‫because these errors, they actually come from Mongoose

275
00:14:27,940 --> 00:14:29,730
‫and so we have no way of adding

276
00:14:29,730 --> 00:14:32,390
‫a status code to these errors.

277
00:14:32,390 --> 00:14:35,370
‫Or actually, of course, we could do it,

278
00:14:35,370 --> 00:14:37,950
‫but that would just be even more confusing

279
00:14:37,950 --> 00:14:40,330
‫and so we're gonna find another way

280
00:14:40,330 --> 00:14:41,443
‫later in this section.

281
00:14:42,510 --> 00:14:45,840
‫For now, I'm really happy with the result that we have here

282
00:14:45,840 --> 00:14:48,773
‫and so that's it for this lecture.

