Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,100 --> 00:00:02,750
In this video, let's now create
2
00:00:02,750 --> 00:00:05,470
a better and more useful error class,
3
00:00:05,470 --> 00:00:07,373
and also do some refactoring.
4
00:00:09,210 --> 00:00:11,870
And starting with that error class,
5
00:00:11,870 --> 00:00:15,053
let's create a new file in our Utilities folder.
6
00:00:15,950 --> 00:00:18,990
So, new file, and I'm going to call it AppError
7
00:00:20,980 --> 00:00:25,820
because that's going to be the name of the class, all right?
8
00:00:25,820 --> 00:00:30,820
So, class AppError, and we actually want all of our
9
00:00:30,867 --> 00:00:34,780
AppError objects to then inherit from the built-in error,
10
00:00:34,780 --> 00:00:39,260
and so let's actually extend the built-in error class.
11
00:00:39,260 --> 00:00:43,720
So, we used extends Error, okay?
12
00:00:43,720 --> 00:00:46,870
So, we did that before somewhere in this course,
13
00:00:46,870 --> 00:00:50,950
and again this is just ES6 classes, all right?
14
00:00:50,950 --> 00:00:52,920
In this case, class inheritance,
15
00:00:52,920 --> 00:00:56,790
where one class inherits from the other, okay?
16
00:00:56,790 --> 00:00:59,300
Then, as always, our constructor,
17
00:00:59,300 --> 00:01:01,800
and what we're going to pass into a new object
18
00:01:01,800 --> 00:01:04,489
created from the AppError class is going to be
19
00:01:04,489 --> 00:01:08,660
the message and the statusCode,
20
00:01:08,660 --> 00:01:09,853
so just these two.
21
00:01:11,330 --> 00:01:15,130
Okay, so, remember the constructor method is called
22
00:01:15,130 --> 00:01:19,210
each time that we create a new object out of this class.
23
00:01:19,210 --> 00:01:22,116
Now, as usual, when we extend a parent class,
24
00:01:22,116 --> 00:01:25,760
we call super in order to call
25
00:01:25,760 --> 00:01:28,203
the parent constructor, all right,
26
00:01:30,100 --> 00:01:33,580
and we do that with message because the message is actually
27
00:01:33,580 --> 00:01:37,160
the only parameter that the built-in error accepts.
28
00:01:37,160 --> 00:01:40,990
Okay, so this is basically you're, like, calling error,
29
00:01:40,990 --> 00:01:44,305
all right, and then this is here is the usual stuff,
30
00:01:44,305 --> 00:01:46,160
we set the statusCode
31
00:01:48,300 --> 00:01:53,030
to statusCode, all right,
32
00:01:53,030 --> 00:01:56,463
and now we also want to set the status itself.
33
00:01:58,200 --> 00:02:01,670
So, remember the status can either be fail or error,
34
00:02:01,670 --> 00:02:03,920
and we could pass that into the object,
35
00:02:03,920 --> 00:02:05,700
but it's also not really necessary,
36
00:02:05,700 --> 00:02:08,530
because the status depends on the statusCode.
37
00:02:08,530 --> 00:02:10,880
So, when the statusCode is a 400,
38
00:02:10,880 --> 00:02:12,630
then the status will be fail,
39
00:02:12,630 --> 00:02:16,230
and if it's a 500, then it's going to be an error, right,
40
00:02:16,230 --> 00:02:18,336
and so that simply tests if the
41
00:02:18,336 --> 00:02:20,420
statusCode starts with a four.
42
00:02:20,420 --> 00:02:23,800
So, in JavaScript, there is a startsWith method
43
00:02:23,800 --> 00:02:25,540
that we can call on strings,
44
00:02:25,540 --> 00:02:28,100
and so I think that's the easiest way of doing this test,
45
00:02:28,100 --> 00:02:31,363
and so that's basically convert the statusCode to a string,
46
00:02:32,780 --> 00:02:35,610
and for that I'm simply using a template string with
47
00:02:35,610 --> 00:02:38,030
the code in there, so this,
48
00:02:38,030 --> 00:02:40,380
or actually we can just use statusCode.
49
00:02:41,781 --> 00:02:42,614
So, statusCode, and then startsWith,
50
00:02:47,001 --> 00:02:48,750
then here we also need a string,
51
00:02:48,750 --> 00:02:51,120
and so if the statusCode as a string
52
00:02:51,120 --> 00:02:54,330
starts with a four, well, then we have a fail.
53
00:02:54,330 --> 00:02:58,360
And so here, let's use the ternary, okay,
54
00:02:58,360 --> 00:03:02,120
and so it's fail when it starts with a four,
55
00:03:02,120 --> 00:03:06,890
and otherwise it's an error, okay?
56
00:03:06,890 --> 00:03:09,550
So, very simple, and this already saves us
57
00:03:09,550 --> 00:03:13,250
from manually have to pass in either fail or error.
58
00:03:13,250 --> 00:03:15,240
All right, now next up,
59
00:03:15,240 --> 00:03:17,120
all the errors that we will create
60
00:03:17,120 --> 00:03:20,300
using this class will all be operational errors.
61
00:03:20,300 --> 00:03:22,070
So, errors that we can predict
62
00:03:22,070 --> 00:03:24,130
will happen in some point in the future,
63
00:03:24,130 --> 00:03:26,010
like for example a user creating
64
00:03:26,010 --> 00:03:29,560
a tour without the required fields, right?
65
00:03:29,560 --> 00:03:32,380
So that is an operational error, okay,
66
00:03:32,380 --> 00:03:34,660
and so again, from now on, we will
67
00:03:34,660 --> 00:03:37,125
always use this AppError class here
68
00:03:37,125 --> 00:03:39,070
that we're creating right now
69
00:03:39,070 --> 00:03:42,230
in order to create all the errors in our application.
70
00:03:42,230 --> 00:03:44,730
And so these errors will be operational errors,
71
00:03:44,730 --> 00:03:46,250
and so what I'm gonna do now is
72
00:03:46,250 --> 00:03:49,663
to actually also create a .is operational property here.
73
00:03:50,980 --> 00:03:53,133
So this.is operational,
74
00:03:56,100 --> 00:03:57,380
and set it to true.
75
00:03:57,380 --> 00:03:59,240
So all of our errors will
76
00:03:59,240 --> 00:04:01,680
get this property set to true,
77
00:04:01,680 --> 00:04:03,420
and I'm doing that so that later
78
00:04:03,420 --> 00:04:05,890
we can then test for this property
79
00:04:05,890 --> 00:04:07,910
and only send error messages back
80
00:04:07,910 --> 00:04:10,360
to the client for these operational errors
81
00:04:10,360 --> 00:04:12,510
that we created using this class.
82
00:04:12,510 --> 00:04:14,550
And this is useful because some other
83
00:04:14,550 --> 00:04:17,209
crazy unexpected errors that might happen
84
00:04:17,209 --> 00:04:19,964
in our application, for example a programming error,
85
00:04:19,964 --> 00:04:22,360
or some bug in one of the packages
86
00:04:22,360 --> 00:04:24,550
that we require into our app,
87
00:04:24,550 --> 00:04:26,100
and these errors will then of course
88
00:04:26,100 --> 00:04:29,610
not have this .is operational property on them,
89
00:04:29,610 --> 00:04:31,610
all right, and it might sound
90
00:04:31,610 --> 00:04:33,370
a bit confusing at this point,
91
00:04:33,370 --> 00:04:35,220
but don't worry, it will make
92
00:04:35,220 --> 00:04:37,040
a lot of sense when we then
93
00:04:37,040 --> 00:04:39,860
implement that part that I just mentioned.
94
00:04:39,860 --> 00:04:43,740
So, testing for this .is operational property here.
95
00:04:43,740 --> 00:04:46,190
All right, and now just one last step
96
00:04:46,190 --> 00:04:50,270
is that we actually also need to capture the stack trace.
97
00:04:50,270 --> 00:04:53,090
Now, what do I mean by stack trace?
98
00:04:53,090 --> 00:04:55,430
And so, let me actually show that to you,
99
00:04:55,430 --> 00:04:58,380
so, show you what stack trace is,
100
00:04:58,380 --> 00:05:01,093
and so I will log it here to the console.
101
00:05:02,180 --> 00:05:05,053
Console.log and error.stackTrace,
102
00:05:06,390 --> 00:05:10,350
so each and every error gets this stack trace,
103
00:05:10,350 --> 00:05:13,370
and actually it's just stack, okay.
104
00:05:13,370 --> 00:05:15,820
So err.stack will basically
105
00:05:15,820 --> 00:05:17,743
show us where the error happened.
106
00:05:19,320 --> 00:05:20,743
So let me run this here now,
107
00:05:22,450 --> 00:05:24,303
and so let's take a look at this,
108
00:05:26,420 --> 00:05:28,000
and so it gives us here the error
109
00:05:28,000 --> 00:05:31,290
and then also where it happened, okay?
110
00:05:31,290 --> 00:05:33,040
So, in this case here, of course,
111
00:05:33,040 --> 00:05:36,390
add app.js at line 32.
112
00:05:36,390 --> 00:05:38,810
So, right here.
113
00:05:38,810 --> 00:05:40,470
So, that's where we created this error,
114
00:05:40,470 --> 00:05:42,200
and so it's now in our stack trace,
115
00:05:42,200 --> 00:05:44,972
and it also shows us the entire call stack here,
116
00:05:44,972 --> 00:05:49,972
which in the end the originated in this error, okay?
117
00:05:50,400 --> 00:05:52,440
So we kind of want to preserve that
118
00:05:52,440 --> 00:05:56,500
and also at the same time not add this method here,
119
00:05:56,500 --> 00:06:00,390
or this class, to that stack track, okay?
120
00:06:00,390 --> 00:06:02,350
And again, that sounds a bit confusing,
121
00:06:02,350 --> 00:06:03,980
I know, but in this case
122
00:06:03,980 --> 00:06:06,359
it's not really important, all that matters
123
00:06:06,359 --> 00:06:09,100
is that we just add this line of code here,
124
00:06:09,100 --> 00:06:11,873
which is Error.capturestackTrace,
125
00:06:13,670 --> 00:06:16,160
so exactly what you get here,
126
00:06:16,160 --> 00:06:19,490
and at first we need to specify the current object,
127
00:06:19,490 --> 00:06:23,530
which is this, and then the AppError class itself,
128
00:06:23,530 --> 00:06:26,113
which is gonna be this.constructor.
129
00:06:28,340 --> 00:06:31,220
Okay, and so this way when a new object
130
00:06:31,220 --> 00:06:34,361
is created, and a constructor function is called,
131
00:06:34,361 --> 00:06:36,388
then that function call is not gonna appear
132
00:06:36,388 --> 00:06:38,863
in the stack trace, and will not pollute it.
133
00:06:40,240 --> 00:06:41,073
All right,
134
00:06:42,250 --> 00:06:44,920
so let's put it down here,
135
00:06:44,920 --> 00:06:48,280
and yeah, so that's our AppError class,
136
00:06:48,280 --> 00:06:51,363
and so let's now actually export it from here.
137
00:06:52,450 --> 00:06:56,443
So, module.exports is of course the AppError.
138
00:06:57,340 --> 00:07:00,367
Great, just one question that you might have is
139
00:07:00,367 --> 00:07:04,720
'Why didn't I set this.message equal to message?'
140
00:07:04,720 --> 00:07:07,600
Well, that's just because right here I called
141
00:07:07,600 --> 00:07:10,253
the parent class, right, and the parent class
142
00:07:10,253 --> 00:07:13,380
is error, and whatever we pass into it
143
00:07:13,380 --> 00:07:15,350
is gonna be the message property.
144
00:07:15,350 --> 00:07:16,860
So just as I told you before.
145
00:07:16,860 --> 00:07:20,880
And so, basically, in here by doing this parent call
146
00:07:20,880 --> 00:07:22,890
we already set the message property
147
00:07:22,890 --> 00:07:24,463
to our incoming message.
148
00:07:25,970 --> 00:07:28,500
All right, give it a save, and now we can close it,
149
00:07:28,500 --> 00:07:29,653
we no longer need it,
150
00:07:30,770 --> 00:07:32,933
and here we're just gonna import it here.
151
00:07:34,621 --> 00:07:35,871
Const AppError,
152
00:07:38,980 --> 00:07:39,883
require,
153
00:07:41,560 --> 00:07:43,600
and then it's in utils,
154
00:07:43,600 --> 00:07:48,320
so Utilities, and appError, okay,
155
00:07:48,320 --> 00:07:51,423
and so now let's actually go ahead and use it.
156
00:07:53,280 --> 00:07:55,070
Comment out this piece of code,
157
00:07:55,070 --> 00:07:57,420
and actually delete the one that we had before,
158
00:07:58,860 --> 00:08:00,210
and that will now create the error
159
00:08:00,210 --> 00:08:02,650
right here inside of next.
160
00:08:02,650 --> 00:08:04,433
So, new AppError,
161
00:08:06,600 --> 00:08:07,783
and then the message,
162
00:08:09,430 --> 00:08:10,793
which is this one,
163
00:08:12,910 --> 00:08:14,023
and the status code.
164
00:08:15,620 --> 00:08:18,410
Right, and the fail, remember, will then automatically
165
00:08:18,410 --> 00:08:22,480
be figured out, and so let's delete all of this,
166
00:08:22,480 --> 00:08:23,723
give it a save here,
167
00:08:25,320 --> 00:08:29,630
and one more time, test out this wrong route,
168
00:08:29,630 --> 00:08:32,940
and indeed we still get our same error,
169
00:08:32,940 --> 00:08:37,530
and we also still get our exact same stack trace.
170
00:08:37,530 --> 00:08:40,280
Okay, and finally I actually also want
171
00:08:40,280 --> 00:08:43,549
to export this middleware here, okay?
172
00:08:43,549 --> 00:08:45,260
So basically, this handler
173
00:08:45,260 --> 00:08:47,150
because throughout the rest of the section,
174
00:08:47,150 --> 00:08:48,760
we're gonna build a couple of different
175
00:08:48,760 --> 00:08:51,700
functions for handling with different types of errors,
176
00:08:51,700 --> 00:08:53,280
and so I want all of these functions
177
00:08:53,280 --> 00:08:55,912
to be all in the same file, all right?
178
00:08:55,912 --> 00:08:58,920
And we can say that all of these functions
179
00:08:58,920 --> 00:09:02,310
that I just mentioned are handlers, okay,
180
00:09:02,310 --> 00:09:05,320
and so handlers, we also call them controllers
181
00:09:05,320 --> 00:09:08,240
in the context of the MVC architecture,
182
00:09:08,240 --> 00:09:10,130
and so let's now actually create
183
00:09:10,130 --> 00:09:13,253
an error controller file in our controller folder.
184
00:09:14,190 --> 00:09:18,280
Okay, and this might sound or look a bit weird
185
00:09:18,280 --> 00:09:21,330
because we actually do not have an error resource
186
00:09:22,200 --> 00:09:24,940
okay, and so probably some people are gonna disagree
187
00:09:24,940 --> 00:09:26,923
with me that this is the correct place,
188
00:09:28,540 --> 00:09:31,100
but I personally like to do it like this
189
00:09:31,100 --> 00:09:32,520
because at the end of the day,
190
00:09:32,520 --> 00:09:34,910
these functions, they kinda are like
191
00:09:34,910 --> 00:09:37,370
really for controlling our errors, all right,
192
00:09:37,370 --> 00:09:39,570
and so for me at least it makes sense
193
00:09:39,570 --> 00:09:43,140
to simply call this function here the error controller,
194
00:09:43,140 --> 00:09:46,500
and here I wanted to paste that middleware function,
195
00:09:46,500 --> 00:09:49,173
but I guess I didn't copy it, so let's do that again.
196
00:09:51,010 --> 00:09:53,540
All right, and so actually I'm gonna export
197
00:09:53,540 --> 00:09:56,240
this one here as the module.exports
198
00:09:56,240 --> 00:09:57,676
because the other handle functions
199
00:09:57,676 --> 00:09:59,606
that we're gonna create later on,
200
00:09:59,606 --> 00:10:02,440
I will not export them from here.
201
00:10:02,440 --> 00:10:05,453
So they are just kinda just gonna be helpers.
202
00:10:06,320 --> 00:10:11,320
So, module.exports equals this function, okay?
203
00:10:12,210 --> 00:10:15,420
Let's actually get rid of this console.log here,
204
00:10:15,420 --> 00:10:18,510
give it a save, and now back into our app
205
00:10:18,510 --> 00:10:21,080
we of course now need to plug in
206
00:10:21,080 --> 00:10:23,040
that middleware function here.
207
00:10:23,040 --> 00:10:25,660
So, let's again go ahead and import it
208
00:10:26,700 --> 00:10:28,710
and I can call it whatever I want,
209
00:10:28,710 --> 00:10:29,760
and so let me call it
210
00:10:30,802 --> 00:10:32,635
the globalErrorHandler
211
00:10:34,679 --> 00:10:36,853
with a capital H,
212
00:10:38,650 --> 00:10:39,840
and I'm gonna require
213
00:10:42,300 --> 00:10:45,033
controllers and errorController.
214
00:10:49,700 --> 00:10:52,660
Put it back here, and now for the final test
215
00:10:52,660 --> 00:10:54,343
after this refactoring.
216
00:10:55,810 --> 00:10:58,970
Let's see, and indeed
217
00:10:58,970 --> 00:11:03,040
one more time, everything works just fine, okay?
218
00:11:03,040 --> 00:11:06,490
So, perfect, that was the goal for this video,
219
00:11:06,490 --> 00:11:07,690
see you in the next one.
16972
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.