﻿1
00:00:01,050 --> 00:00:02,840
‫Let's now make some more use

2
00:00:02,840 --> 00:00:04,780
‫of our AppError class

3
00:00:04,780 --> 00:00:07,400
‫business adding a couple of 404 errors

4
00:00:07,400 --> 00:00:09,493
‫and some of our tour handler functions.

5
00:00:10,446 --> 00:00:12,740
‫Now just one thing that I wanted to say

6
00:00:12,740 --> 00:00:16,030
‫before we actually implement these 404 errors

7
00:00:16,030 --> 00:00:19,640
‫is that of course we could have used the catchAsync function

8
00:00:19,640 --> 00:00:22,290
‫also in our router, okay?

9
00:00:22,290 --> 00:00:24,940
‫So, let me show you how that would work.

10
00:00:24,940 --> 00:00:27,090
‫So, here in TourRoutes,

11
00:00:27,090 --> 00:00:29,730
‫I could have wrapped this function here

12
00:00:30,750 --> 00:00:34,530
‫into catchAsync just like this

13
00:00:34,530 --> 00:00:38,480
‫instead of doing it right in here in the controller.

14
00:00:38,480 --> 00:00:41,400
‫So, here where I did it in fact, right?

15
00:00:41,400 --> 00:00:44,200
‫And that would have had the exact same result

16
00:00:44,200 --> 00:00:45,950
‫but I didn't do it this way

17
00:00:45,950 --> 00:00:48,190
‫because like this, I have to remember

18
00:00:48,190 --> 00:00:50,110
‫which of these methods here

19
00:00:50,110 --> 00:00:52,350
‫is actually an sync method,

20
00:00:52,350 --> 00:00:54,800
‫okay, so that only on those

21
00:00:54,800 --> 00:00:58,960
‫I actually add the catchAsync function, right?

22
00:00:58,960 --> 00:01:02,150
‫Now in this case, actually all of them are async function

23
00:01:02,150 --> 00:01:05,700
‫and so, that's not really the matter here in this example

24
00:01:05,700 --> 00:01:07,530
‫but there will be some examples later

25
00:01:07,530 --> 00:01:11,150
‫where not all the handlers are asynchronous functions

26
00:01:11,150 --> 00:01:12,170
‫and so, in that case,

27
00:01:12,170 --> 00:01:14,020
‫I would really have to remember

28
00:01:14,020 --> 00:01:17,100
‫which of them I have to wrap into catchAsync

29
00:01:17,100 --> 00:01:18,600
‫and which ones not

30
00:01:18,600 --> 00:01:20,450
‫and so, in doing it in the controller

31
00:01:20,450 --> 00:01:23,930
‫is much easier because simply each time that I'm writing

32
00:01:23,930 --> 00:01:25,520
‫an async function here,

33
00:01:25,520 --> 00:01:27,190
‫they already know well,

34
00:01:27,190 --> 00:01:30,220
‫I need to wrap it into catchAsync.

35
00:01:30,220 --> 00:01:31,350
‫Okay.

36
00:01:31,350 --> 00:01:32,880
‫So, I'm not doing it here,

37
00:01:32,880 --> 00:01:36,400
‫I just do it like I showed you in the last video.

38
00:01:36,400 --> 00:01:39,680
‫Okay and actually I once run into a bug

39
00:01:39,680 --> 00:01:41,330
‫that was really hard to find

40
00:01:41,330 --> 00:01:43,160
‫because I actually wrapped a function

41
00:01:43,160 --> 00:01:45,690
‫that was not async into catchAsync

42
00:01:45,690 --> 00:01:47,850
‫and so that we really not working

43
00:01:47,850 --> 00:01:50,350
‫and I couldn't figure out where the bug was

44
00:01:50,350 --> 00:01:52,830
‫and wasted a lot of time on that one.

45
00:01:52,830 --> 00:01:56,820
‫And so, since then, I no longer put catchAsync here

46
00:01:56,820 --> 00:01:59,610
‫but really close to where I actually need it,

47
00:01:59,610 --> 00:02:02,860
‫so close to the code that is actually asynchronous.

48
00:02:02,860 --> 00:02:04,640
‫Okay and with that being said,

49
00:02:04,640 --> 00:02:07,820
‫let's now implement some 404 errors here.

50
00:02:07,820 --> 00:02:09,680
‫All right, so I wanna start

51
00:02:09,680 --> 00:02:11,680
‫by showing you again the example

52
00:02:11,680 --> 00:02:13,830
‫that we did in the last video.

53
00:02:13,830 --> 00:02:16,350
‫Okay, so we tried to get a tour

54
00:02:16,350 --> 00:02:19,780
‫for this weird ID that does not really exist

55
00:02:19,780 --> 00:02:20,989
‫and the error that we got

56
00:02:20,989 --> 00:02:23,690
‫is that basically Mongoose

57
00:02:23,690 --> 00:02:26,410
‫could not convert this string here

58
00:02:26,410 --> 00:02:29,630
‫into a valid ID for MongoDB.

59
00:02:29,630 --> 00:02:33,653
‫But what happens when we actually use a valid MongoDB ID?

60
00:02:34,750 --> 00:02:38,003
‫So, for example, let's, yeah,

61
00:02:38,003 --> 00:02:39,173
‫let's copy this one here,

62
00:02:41,660 --> 00:02:44,670
‫okay, and this one of course will have a result

63
00:02:44,670 --> 00:02:47,770
‫and so, let's just slightly change it,

64
00:02:47,770 --> 00:02:50,060
‫so for example, changing this to zero here

65
00:02:50,060 --> 00:02:52,340
‫will still be a valid ID,

66
00:02:52,340 --> 00:02:53,900
‫so it looks like this

67
00:02:53,900 --> 00:02:56,000
‫and it looks exactly the same as before,

68
00:02:56,000 --> 00:02:57,440
‫I just changed one number

69
00:02:57,440 --> 00:03:00,830
‫but this ID will probably not exist.

70
00:03:00,830 --> 00:03:03,470
‫And so, let's see what we get then.

71
00:03:03,470 --> 00:03:06,810
‫And indeed, now our result here is null.

72
00:03:06,810 --> 00:03:10,340
‫All right, and so, that's not really what we want, is it?

73
00:03:10,340 --> 00:03:14,550
‫What we want here is to show a 404 status code in here

74
00:03:14,550 --> 00:03:17,310
‫and say that this tour was not found.

75
00:03:17,310 --> 00:03:20,750
‫Okay and so, let's now use orAppError class

76
00:03:20,750 --> 00:03:22,580
‫in order to implement that.

77
00:03:22,580 --> 00:03:24,040
‫Just keep in mind that the tour

78
00:03:24,040 --> 00:03:26,880
‫that we get back here is null, okay?

79
00:03:26,880 --> 00:03:29,453
‫So, null that we can now test for.

80
00:03:30,920 --> 00:03:33,533
‫So, if we go to our getTour handler,

81
00:03:35,260 --> 00:03:40,260
‫let's now implement if there is no tour

82
00:03:41,030 --> 00:03:43,390
‫and in that case we will create or error

83
00:03:44,410 --> 00:03:45,243
‫and this here works

84
00:03:45,243 --> 00:03:46,650
‫because if there's no tour,

85
00:03:46,650 --> 00:03:47,710
‫it will be null.

86
00:03:47,710 --> 00:03:51,610
‫Remember and in JavaScript, null is a fallacy value,

87
00:03:51,610 --> 00:03:54,660
‫so a value that will convert to false here

88
00:03:54,660 --> 00:03:56,250
‫in an if statement.

89
00:03:56,250 --> 00:03:58,060
‫Okay, and so, if there's no tour,

90
00:03:58,060 --> 00:03:59,450
‫then tour is false

91
00:03:59,450 --> 00:04:01,790
‫and then not false is of course true

92
00:04:01,790 --> 00:04:04,830
‫and so, that's then how we enter this if block.

93
00:04:04,830 --> 00:04:07,600
‫So, what do we want to do if there is no tour?

94
00:04:07,600 --> 00:04:11,530
‫Well, we want to create next with an error.

95
00:04:11,530 --> 00:04:14,861
‫So, in order to jump straight into or error

96
00:04:14,861 --> 00:04:15,990
‫and linked middleware.

97
00:04:15,990 --> 00:04:18,870
‫So, we do new AppError

98
00:04:20,610 --> 00:04:23,350
‫which si not available yet, we still have to import it

99
00:04:23,350 --> 00:04:26,120
‫but let's use it here right away.

100
00:04:26,120 --> 00:04:27,950
‫Okay, and then let's just say

101
00:04:30,500 --> 00:04:34,673
‫No tour found with that ID.

102
00:04:35,580 --> 00:04:37,070
‫And then a status code remember

103
00:04:37,070 --> 00:04:40,940
‫is the second argument is 404, all right?

104
00:04:40,940 --> 00:04:43,460
‫Now one last thing that we need to do here

105
00:04:43,460 --> 00:04:46,470
‫which is to say return, okay

106
00:04:46,470 --> 00:04:49,410
‫because we want to return this function immediately

107
00:04:49,410 --> 00:04:52,250
‫and not move on to the next line

108
00:04:52,250 --> 00:04:53,690
‫which would be this one

109
00:04:53,690 --> 00:04:57,800
‫and which would then basically try to send two responses

110
00:04:57,800 --> 00:05:00,210
‫and we did already run into that error before,

111
00:05:00,210 --> 00:05:02,020
‫so I'll hope you'll remember that

112
00:05:02,020 --> 00:05:05,580
‫and that's the reason why we always need return here.

113
00:05:05,580 --> 00:05:09,610
‫Okay, let's now go ahead and quickly import the appError

114
00:05:10,870 --> 00:05:13,200
‫and that's similar to this one here,

115
00:05:13,200 --> 00:05:14,823
‫so let's just duplicate.

116
00:05:17,990 --> 00:05:21,203
‫Okay, and here it's actually with a capital A.

117
00:05:22,170 --> 00:05:24,210
‫All right, give it a save

118
00:05:24,210 --> 00:05:25,850
‫and let's now try it again

119
00:05:27,160 --> 00:05:31,450
‫and now indeed no tour found with that ID 404.

120
00:05:31,450 --> 00:05:34,440
‫Perfect, so exactly what we wanted.

121
00:05:34,440 --> 00:05:37,170
‫Oh and you also saw that we have the failed here.

122
00:05:37,170 --> 00:05:40,980
‫Okay and so that comes from or class as well.

123
00:05:40,980 --> 00:05:44,270
‫Great, so that works and so I really hope

124
00:05:44,270 --> 00:05:48,060
‫that by now you understood exactly how all

125
00:05:48,060 --> 00:05:50,370
‫of this error handling now works.

126
00:05:50,370 --> 00:05:53,300
‫Okay, so again we create an error

127
00:05:53,300 --> 00:05:55,450
‫and we then pass that error into next

128
00:05:55,450 --> 00:05:57,820
‫and as soon as next receives something,

129
00:05:57,820 --> 00:05:59,880
‫it assumes that it is an error

130
00:05:59,880 --> 00:06:00,757
‫and it will jump straight

131
00:06:00,757 --> 00:06:03,630
‫into the global error handling middleware

132
00:06:03,630 --> 00:06:06,683
‫which will then send the response for us, okay?

133
00:06:08,210 --> 00:06:09,850
‫So, let's copy this one

134
00:06:09,850 --> 00:06:12,410
‫and put it in all the other handlers

135
00:06:12,410 --> 00:06:15,600
‫that query documents based on the ID.

136
00:06:15,600 --> 00:06:20,470
‫So, not create tour but update a tour, okay?

137
00:06:20,470 --> 00:06:21,380
‫And so, here the same,

138
00:06:21,380 --> 00:06:23,120
‫if we're trying to update the tour

139
00:06:23,120 --> 00:06:24,360
‫that does not exist,

140
00:06:24,360 --> 00:06:26,773
‫it will then give us the exact same error.

141
00:06:29,210 --> 00:06:32,470
‫Finally of course the same with delete.

142
00:06:32,470 --> 00:06:35,870
‫And now you see that ESLint gave me this error here

143
00:06:35,870 --> 00:06:38,710
‫and so, that's because this tour is not defined

144
00:06:38,710 --> 00:06:41,730
‫and in this case, ESLint really saved me here

145
00:06:41,730 --> 00:06:43,660
‫from creating this bug.

146
00:06:43,660 --> 00:06:44,550
‫Right?

147
00:06:44,550 --> 00:06:46,790
‫So, again without ESLint,

148
00:06:46,790 --> 00:06:48,570
‫I would have probably just pasted it here

149
00:06:48,570 --> 00:06:49,920
‫and called it a day

150
00:06:49,920 --> 00:06:53,050
‫without even noticing that tour is nowhere defined

151
00:06:53,050 --> 00:06:54,600
‫inside of this function

152
00:06:54,600 --> 00:06:57,830
‫but since we installed this really valuable tool,

153
00:06:57,830 --> 00:06:59,970
‫I can now go ahead and fix it.

154
00:06:59,970 --> 00:07:01,820
‫All right, so up until this point,

155
00:07:01,820 --> 00:07:06,490
‫we simply awaited this delete instruction here

156
00:07:06,490 --> 00:07:08,460
‫and didn't save the result of it

157
00:07:08,460 --> 00:07:10,710
‫and that's simply because we didn't need it.

158
00:07:10,710 --> 00:07:13,200
‫Okay, but right now we actually do need it

159
00:07:13,200 --> 00:07:15,140
‫because we want this tour variable

160
00:07:15,140 --> 00:07:18,413
‫in order to verify if there actually is a tour or not.

161
00:07:21,460 --> 00:07:23,760
‫So, very easy, const tour

162
00:07:23,760 --> 00:07:25,350
‫and then equal to that result,

163
00:07:25,350 --> 00:07:27,450
‫give it a save and then the error is gone.

164
00:07:28,610 --> 00:07:29,820
‫So, great.

165
00:07:29,820 --> 00:07:32,770
‫ESLint at work, all right?

166
00:07:32,770 --> 00:07:37,770
‫Now maybe you noticed that I did not add this 404 error here

167
00:07:37,950 --> 00:07:40,000
‫in this getAllTour handler.

168
00:07:40,000 --> 00:07:41,910
‫So, why did I did that?

169
00:07:41,910 --> 00:07:43,620
‫And so let me explain you why.

170
00:07:43,620 --> 00:07:46,330
‫So, when there is zero results found,

171
00:07:46,330 --> 00:07:50,530
‫for example, there are no results matching for a filter,

172
00:07:50,530 --> 00:07:52,520
‫or because the page was requested

173
00:07:52,520 --> 00:07:55,970
‫that doesn't exist, then of course we could consider sending

174
00:07:55,970 --> 00:07:58,550
‫a 404 error and saying that the data

175
00:07:58,550 --> 00:08:01,220
‫was not found but in my opinion

176
00:08:01,220 --> 00:08:03,760
‫and also the opinion of other developers,

177
00:08:03,760 --> 00:08:07,170
‫that is not entirely correct in this request

178
00:08:07,170 --> 00:08:09,240
‫because there was not really an error.

179
00:08:09,240 --> 00:08:11,950
‫I mean, the request was correctly received.

180
00:08:11,950 --> 00:08:14,550
‫The database correctly searched for the tours

181
00:08:14,550 --> 00:08:16,950
‫and found exactly zero records

182
00:08:16,950 --> 00:08:19,150
‫and so, these zero records are exactly

183
00:08:19,150 --> 00:08:23,250
‫what we're gonna send back along with the 200 HTTP code.

184
00:08:23,250 --> 00:08:25,120
‫All right, so again I consider

185
00:08:25,120 --> 00:08:27,300
‫that there cannot really be an error

186
00:08:27,300 --> 00:08:29,610
‫when a user requests all the tours

187
00:08:29,610 --> 00:08:32,680
‫unless of course there is some failure in the database

188
00:08:32,680 --> 00:08:33,850
‫or something like that.

189
00:08:33,850 --> 00:08:35,210
‫But in that case, Mongoose

190
00:08:35,210 --> 00:08:37,600
‫will then automatically throw an error.

191
00:08:37,600 --> 00:08:40,950
‫Right, which then in turn is gonna get catched

192
00:08:40,950 --> 00:08:42,920
‫by our or catchAsync function

193
00:08:42,920 --> 00:08:44,330
‫and as you already know,

194
00:08:44,330 --> 00:08:47,510
‫handled in our global error handler

195
00:08:47,510 --> 00:08:48,800
‫and as you already know,

196
00:08:48,800 --> 00:08:52,000
‫handled in our global error handling middleware.

197
00:08:52,000 --> 00:08:55,640
‫All right, so I've said these words so many times by now.

198
00:08:55,640 --> 00:08:57,717
‫Anyway, I hope that made sense

199
00:08:57,717 --> 00:09:01,113
‫and so, yeah, let's now move on.

