﻿1
00:00:00,920 --> 00:00:02,913
‫So as I mentioned in the last video

2
00:00:02,913 --> 00:00:05,243
‫there are three types of errors

3
00:00:05,243 --> 00:00:07,525
‫that might be created by Mongoose

4
00:00:07,525 --> 00:00:10,520
‫in which we need to mark as operational errors

5
00:00:10,520 --> 00:00:13,700
‫so that we can send back meaningful error messages

6
00:00:13,700 --> 00:00:15,383
‫to clients in production.

7
00:00:16,890 --> 00:00:21,290
‫And let's now start by simulating these three errors, okay?

8
00:00:21,290 --> 00:00:25,263
‫So the first one is when we try an invalid ID here,

9
00:00:26,240 --> 00:00:28,180
‫so simply something like this,

10
00:00:28,180 --> 00:00:30,950
‫and so Mongoose will not be able to convert this

11
00:00:30,950 --> 00:00:33,427
‫into a MongoDB ID, remember that.

12
00:00:33,427 --> 00:00:36,799
‫And so this is the error that we get right now,

13
00:00:36,799 --> 00:00:39,650
‫and actually, here you can see all the kind of stuff

14
00:00:39,650 --> 00:00:42,950
‫that we defined we wanted to see in productions.

15
00:00:42,950 --> 00:00:47,010
‫So the entire error object, then the error message,

16
00:00:47,010 --> 00:00:50,590
‫and also the complete stack, okay?

17
00:00:50,590 --> 00:00:53,180
‫And so this is a perfect example

18
00:00:53,180 --> 00:00:54,500
‫of an operational error.

19
00:00:54,500 --> 00:00:57,160
‫So this is something that might very well happen,

20
00:00:57,160 --> 00:01:00,060
‫and so we need to send back a meaningful response

21
00:01:00,060 --> 00:01:02,380
‫in order to handle this error.

22
00:01:02,380 --> 00:01:05,590
‫And this is a perfect example of an operational error

23
00:01:05,590 --> 00:01:09,260
‫that is very likely to at some point happen to a client,

24
00:01:09,260 --> 00:01:11,740
‫and so, we need to handle it as one, alright?

25
00:01:11,740 --> 00:01:14,607
‫So, basically by sending a nice error message

26
00:01:14,607 --> 00:01:16,690
‫instead of something like this,

27
00:01:16,690 --> 00:01:20,181
‫which doesn't mean anything to any client, right?

28
00:01:20,181 --> 00:01:22,500
‫Okay, so the goal here again

29
00:01:22,500 --> 00:01:26,120
‫will be to basically mark this error as operational,

30
00:01:26,120 --> 00:01:28,880
‫and create a meaningful message, alright?

31
00:01:28,880 --> 00:01:30,580
‫But before we can do that, let's take a look

32
00:01:30,580 --> 00:01:32,620
‫at the other two Mongoose errors

33
00:01:32,620 --> 00:01:36,260
‫that we also will have to mark as operational, okay?

34
00:01:36,260 --> 00:01:38,457
‫So, let's Create a New Tour,

35
00:01:38,457 --> 00:01:43,236
‫and what I'm gonna do is to create a duplicate name.

36
00:01:43,236 --> 00:01:46,210
‫So, let's just copy this one here.

37
00:01:50,347 --> 00:01:52,503
‫And I think all the values here are correct,

38
00:01:52,503 --> 00:01:54,780
‫so let's try this now.

39
00:01:54,780 --> 00:01:58,520
‫And indeed, here we get the error that we already know,

40
00:01:58,520 --> 00:02:00,210
‫which is duplicate key error

41
00:02:00,210 --> 00:02:01,960
‫because we already have a tour,

42
00:02:01,960 --> 00:02:05,740
‫or a document with the name of Forest Hiker, okay?

43
00:02:05,740 --> 00:02:07,440
‫So again, this is an error

44
00:02:07,440 --> 00:02:09,420
‫that is going to happen at some point,

45
00:02:09,420 --> 00:02:10,720
‫and again, it doesn't have

46
00:02:10,720 --> 00:02:13,650
‫a very meaningful error message, right?

47
00:02:13,650 --> 00:02:16,243
‫And so again, we need to change that.

48
00:02:17,200 --> 00:02:19,954
‫Then the third one is also kind of about validation,

49
00:02:19,954 --> 00:02:23,980
‫and so let's do that here in Update Tour.

50
00:02:23,980 --> 00:02:27,835
‫So, let's say that we want to have a ratingsAverage of six,

51
00:02:27,835 --> 00:02:30,700
‫which we know is invalid, right?

52
00:02:30,700 --> 00:02:33,430
‫Because we said that the max of ratingsAverage

53
00:02:33,430 --> 00:02:34,960
‫could be five.

54
00:02:34,960 --> 00:02:36,720
‫So let's see, and indeed,

55
00:02:36,720 --> 00:02:40,891
‫we get this ValidationError, right?

56
00:02:40,891 --> 00:02:43,300
‫So it's called a ValidationError,

57
00:02:43,300 --> 00:02:47,600
‫and it has this errors object with all the errors.

58
00:02:47,600 --> 00:02:49,400
‫Let's actually put another one here.

59
00:02:51,377 --> 00:02:53,183
‫So let's say difficulty,

60
00:02:55,229 --> 00:02:57,110
‫and then something else,

61
00:02:57,110 --> 00:02:59,981
‫so one that's not easy, medium, or difficult,

62
00:02:59,981 --> 00:03:03,540
‫and so now we get these two objects here.

63
00:03:03,540 --> 00:03:08,090
‫Ones for the ratings, and one for the difficulty, alright?

64
00:03:08,090 --> 00:03:09,800
‫So these are the three errors

65
00:03:09,800 --> 00:03:11,740
‫that we're gonna mark as operational,

66
00:03:11,740 --> 00:03:14,110
‫starting with this first one,

67
00:03:14,110 --> 00:03:17,540
‫so basically, the CastError type, okay?

68
00:03:17,540 --> 00:03:20,250
‫So, let's go back here, and we're gonna do that here,

69
00:03:20,250 --> 00:03:24,260
‫again, because we only want to do this in production, okay?

70
00:03:24,260 --> 00:03:26,570
‫In development, we don't care about any of this.

71
00:03:26,570 --> 00:03:28,576
‫All we want to do is see our errors

72
00:03:28,576 --> 00:03:30,910
‫so that we can basically fix them,

73
00:03:30,910 --> 00:03:33,220
‫but in production, this is where we want to send

74
00:03:33,220 --> 00:03:36,110
‫the meaningful error messages to the clients.

75
00:03:36,110 --> 00:03:40,690
‫So, let's say if err.name

76
00:03:40,690 --> 00:03:45,690
‫is equal to CastError,

77
00:03:45,980 --> 00:03:48,400
‫and so that's how we're going to identify

78
00:03:48,400 --> 00:03:51,000
‫this type of error here that we just talked about,

79
00:03:51,000 --> 00:03:55,300
‫because it has the name of CastError, alright?

80
00:03:55,300 --> 00:03:57,564
‫So if err.name is CastError,

81
00:03:57,564 --> 00:04:02,230
‫well then we're gonna call a special function

82
00:04:02,230 --> 00:04:03,880
‫that we're gonna create in a second,

83
00:04:03,880 --> 00:04:06,097
‫which is called handleCastError.

84
00:04:10,750 --> 00:04:14,290
‫And then I'm also gonna say here DB for database,

85
00:04:14,290 --> 00:04:18,320
‫so that we know that this is related to our database, okay?

86
00:04:18,320 --> 00:04:19,920
‫And this is how it's gonna work.

87
00:04:19,920 --> 00:04:21,470
‫We're gonna pass the error

88
00:04:21,470 --> 00:04:23,683
‫that Mongoose created into this function,

89
00:04:24,720 --> 00:04:27,070
‫so just like this, and this will then return

90
00:04:27,070 --> 00:04:30,840
‫a new error created with out AppError class, okay?

91
00:04:30,840 --> 00:04:33,930
‫And that error will then be marked as operational,

92
00:04:33,930 --> 00:04:36,120
‫because remember, all our AppErrors

93
00:04:36,120 --> 00:04:38,030
‫have the is operational properties

94
00:04:38,030 --> 00:04:40,523
‫set to two automatically, right?

95
00:04:41,820 --> 00:04:46,390
‫So this will return an error, and so, let's save that, okay?

96
00:04:46,390 --> 00:04:49,260
‫And so were saving that in err.

97
00:04:49,260 --> 00:04:51,050
‫Now it's not a good practice at all

98
00:04:51,050 --> 00:04:54,700
‫to override the arguments of a function, okay?

99
00:04:54,700 --> 00:04:57,930
‫So error comes from this middle err function, right?

100
00:04:57,930 --> 00:05:01,020
‫So, from here, and so instead of doing that,

101
00:05:01,020 --> 00:05:03,217
‫I will actually create a hard copy

102
00:05:03,217 --> 00:05:06,516
‫of that error object, okay?

103
00:05:06,516 --> 00:05:09,760
‫So let, and I'm using let, and not const,

104
00:05:09,760 --> 00:05:11,700
‫because we will of course reassign

105
00:05:11,700 --> 00:05:14,043
‫a new error then, later here.

106
00:05:15,490 --> 00:05:18,820
‫So, let's call this one error instead of just err,

107
00:05:18,820 --> 00:05:22,250
‫which is the normal name of errors in Express.

108
00:05:22,250 --> 00:05:24,710
‫And so again, we're gonna use our trick

109
00:05:24,710 --> 00:05:29,133
‫where we use destructuring of the original error, okay?

110
00:05:30,930 --> 00:05:34,257
‫And so, from now on, we will use this error instead of err.

111
00:05:35,620 --> 00:05:38,963
‫So here, and here, and here.

112
00:05:41,720 --> 00:05:42,770
‫Alright?

113
00:05:42,770 --> 00:05:44,890
‫And so, let's now go ahead

114
00:05:44,890 --> 00:05:47,223
‫and actually create this function here.

115
00:05:49,580 --> 00:05:52,883
‫So let's put that up here right in the beginning.

116
00:05:56,247 --> 00:05:57,413
‫Alright.

117
00:05:58,270 --> 00:06:00,680
‫Try to remember that this receives an error,

118
00:06:00,680 --> 00:06:04,210
‫and now I'm going back to just calling it err like this,

119
00:06:04,210 --> 00:06:07,320
‫because again that's kind of the standard in Express.

120
00:06:07,320 --> 00:06:09,020
‫And to start, let's take a look again

121
00:06:09,020 --> 00:06:12,910
‫at the error object here, okay?

122
00:06:12,910 --> 00:06:17,910
‫So here, we have the path, and we have also the value, okay?

123
00:06:18,290 --> 00:06:21,280
‫So the path here is basically the name of the field

124
00:06:21,280 --> 00:06:25,000
‫for which the input data is in the wrong format, okay?

125
00:06:25,000 --> 00:06:27,860
‫And that value here is then this one,

126
00:06:27,860 --> 00:06:31,050
‫which is, of course, the one that we past did, alright?

127
00:06:31,050 --> 00:06:34,200
‫So, this might not only happen for the ID,

128
00:06:34,200 --> 00:06:36,450
‫but really, for any field that we query for

129
00:06:36,450 --> 00:06:39,370
‫with a value in the wrong format, alright?

130
00:06:39,370 --> 00:06:41,270
‫And so, let's now basically create a string

131
00:06:41,270 --> 00:06:43,330
‫that says that we have an invalid ID

132
00:06:43,330 --> 00:06:48,330
‫with the value of this one in this case, alright?

133
00:06:48,360 --> 00:06:53,360
‫So, it's path and value, okay?

134
00:06:53,530 --> 00:06:55,873
‫So, let's create a message here,

135
00:06:59,780 --> 00:07:01,770
‫and say Invalid err.path

136
00:07:08,328 --> 00:07:09,411
‫is err.value.

137
00:07:13,870 --> 00:07:15,250
‫Okay?

138
00:07:15,250 --> 00:07:17,813
‫And so now, we simply return our own AppError.

139
00:07:18,990 --> 00:07:20,227
‫Okay?

140
00:07:20,227 --> 00:07:24,270
‫So just like I mentioned a couple of times by now, okay?

141
00:07:24,270 --> 00:07:27,740
‫So AppError, and I actually have to include it here,

142
00:07:27,740 --> 00:07:30,933
‫or to require, because I didn't do it yet.

143
00:07:31,940 --> 00:07:35,633
‫So const AppError is equal to require,

144
00:07:39,150 --> 00:07:42,620
‫and move one level up, then into the utilities folder,

145
00:07:42,620 --> 00:07:45,213
‫and then the appError.

146
00:07:46,350 --> 00:07:47,183
‫Here it is.

147
00:07:48,150 --> 00:07:52,570
‫And so now, into or AppError, we pass in our message,

148
00:07:52,570 --> 00:07:56,860
‫and the 400 status code, which stands for Bad Request.

149
00:07:56,860 --> 00:07:59,040
‫Okay, and so just like this,

150
00:07:59,040 --> 00:08:00,940
‫we transform the weird error

151
00:08:00,940 --> 00:08:02,640
‫that we were getting from Mongoose

152
00:08:02,640 --> 00:08:04,110
‫into an operational error

153
00:08:04,110 --> 00:08:06,354
‫with a nice friendly message that

154
00:08:06,354 --> 00:08:07,187
‫(chuckles)

155
00:08:07,187 --> 00:08:09,343
‫an actual human can read, alright?

156
00:08:10,684 --> 00:08:13,270
‫Okay, one last thing that we need to change here

157
00:08:13,270 --> 00:08:18,150
‫is to also set this one here to error, okay?

158
00:08:18,150 --> 00:08:21,750
‫And so, right now, if our error is CastError,

159
00:08:21,750 --> 00:08:24,770
‫well, we will then pass the error into this function

160
00:08:24,770 --> 00:08:27,790
‫which will return our AppError, so this one,

161
00:08:27,790 --> 00:08:31,430
‫and that is the one that will then be sent to the client

162
00:08:31,430 --> 00:08:34,180
‫using our sendErrorProd, okay?

163
00:08:34,180 --> 00:08:36,123
‫And so, let's now actually try that.

164
00:08:37,080 --> 00:08:39,060
‫So here, in our package.json,

165
00:08:39,060 --> 00:08:43,627
‫we have this start:prod script, and so let's try that.

166
00:08:43,627 --> 00:08:48,627
‫So, npm run start:prod, and I can actually auto complete

167
00:08:50,250 --> 00:08:54,580
‫these npm script names using tab here in the terminal, okay?

168
00:08:54,580 --> 00:08:56,420
‫And so, this will start a process

169
00:08:56,420 --> 00:08:59,640
‫in production mode, basically, okay?

170
00:08:59,640 --> 00:09:01,060
‫And so, let's now try this again.

171
00:09:01,060 --> 00:09:02,580
‫So, if you're now doing this request,

172
00:09:02,580 --> 00:09:04,350
‫we should get back the error message

173
00:09:04,350 --> 00:09:07,500
‫that we just created, 'cause right now, we're in production.

174
00:09:07,500 --> 00:09:10,060
‫And indeed, here it is.

175
00:09:10,060 --> 00:09:12,530
‫So we have invalid, and then field name,

176
00:09:12,530 --> 00:09:15,010
‫or actually the path name, and then the value

177
00:09:15,010 --> 00:09:15,843
‫that we put in.

178
00:09:17,130 --> 00:09:19,194
‫So if we try something different, then of course,

179
00:09:19,194 --> 00:09:21,730
‫we get this, and of course,

180
00:09:21,730 --> 00:09:25,450
‫also our 400 Bad Request code.

181
00:09:25,450 --> 00:09:26,650
‫Okay, great.

182
00:09:26,650 --> 00:09:28,533
‫So, this one is now handled.

183
00:09:28,533 --> 00:09:32,210
‫In the next lecture, we will then take care of the next one,

184
00:09:32,210 --> 00:09:35,440
‫which is for duplicate field names, alright?

185
00:09:35,440 --> 00:09:36,890
‫So, see you then in a second.

