Coding

Handling Errors & Improving the Project Setup | Creating a REST API with Node.js

  • 00:00:01 welcome back to the serious over the
  • 00:00:04 last videos we already worked quite a
  • 00:00:06 bit on our restful api and I liked how
  • 00:00:10 it looked said works really great now we
  • 00:00:14 added some routes and zhan it's now time
  • 00:00:16 to improve our development set up a
  • 00:00:18 little bit at least and I always want to
  • 00:00:20 make sure that we improve error handling
  • 00:00:23 because we're not really handling errors
  • 00:00:25 in our API as of now
  • 00:00:31 so first of all what I want to improve
  • 00:00:34 regarding the setup is I don't
  • 00:00:36 constantly want to restart the server
  • 00:00:39 whenever we make a change to anything
  • 00:00:41 for this we can use a package called
  • 00:00:43 node Mon we install it with the NPM
  • 00:00:46 install and then – – save def because 3
  • 00:00:49 is only a development dependency we need
  • 00:00:51 and then the name is just node Mon just
  • 00:00:53 download it like this this is a package
  • 00:00:56 which will basically monitor your files
  • 00:00:58 and automatically restart the server
  • 00:01:00 whenever you change something a link to
  • 00:01:03 the package can be found in the video
  • 00:01:05 description and there you can learn more
  • 00:01:07 about it so now with that note one was
  • 00:01:10 added I now also want you no longer
  • 00:01:14 manually type note server but instead
  • 00:01:17 with node Mon we would have to type node
  • 00:01:20 Mon server je s that however will fail
  • 00:01:23 because it's not a global package
  • 00:01:25 installed on our machine now we can
  • 00:01:29 easily work around this by going to the
  • 00:01:31 package.json file and adding a script
  • 00:01:34 let's add the start script that's a
  • 00:01:37 special script we can easily execute by
  • 00:01:40 running NPM start inside our project
  • 00:01:42 folder and when we type this I want to
  • 00:01:45 run node 1 here I can use that because
  • 00:01:49 this will now not search for it on our
  • 00:01:51 cert system but in our project and there
  • 00:01:54 we just installed it so then I want to
  • 00:01:56 execute node 1 server je s now if I run
  • 00:02:00 NPM start here you see we got this
  • 00:02:03 output here looks a little bit different
  • 00:02:05 than before and it essentially started
  • 00:02:07 our server so if I go back to postman
  • 00:02:11 and I try my requests again this still
  • 00:02:14 works because we got a no js' server but
  • 00:02:17 watch the console if I added something
  • 00:02:20 so here I'll simply add a comment routes
  • 00:02:25 which should handle requests and now if
  • 00:02:28 I save this file
  • 00:02:30 you see it's restarting the server even
  • 00:02:33 though here I didn't add any logic that
  • 00:02:35 would have required that but it watched
  • 00:02:36 the file and saw that I changed it and
  • 00:02:39 this all the works for files and
  • 00:02:41 subdirectories here if I say handle
  • 00:02:44 incoming get requests to slash orders
  • 00:02:48 and I save this
  • 00:02:50 it also restarted so this is really
  • 00:02:53 convenient now we don't have to manually
  • 00:02:55 cancel the server and restart whatever
  • 00:02:57 make a change
  • 00:02:59 additionally I want to add a logging
  • 00:03:01 package to my set up to log incoming
  • 00:03:05 requests so that we can also see some
  • 00:03:07 information here in the terminal so for
  • 00:03:10 that I'll temporarily quit node Mon and
  • 00:03:13 install another package with NPM install
  • 00:03:16 – – save and it's called Morgan
  • 00:03:19 it's a logging package for node J s we
  • 00:03:22 can use it really easy just go to app J
  • 00:03:26 s and there let's create a new constant
  • 00:03:29 its name at Morgan and require the name
  • 00:03:33 is by the way totally up to you
  • 00:03:34 require Morgan this name is not up to
  • 00:03:36 you that has to be the package you
  • 00:03:37 installed and now we have to basically
  • 00:03:40 tell Express to funnel all requests
  • 00:03:43 through this middleware that it is in
  • 00:03:46 the end and Morgan will then just log
  • 00:03:48 something and let the request continue
  • 00:03:50 so Morgan behind the scenes will call
  • 00:03:53 this next function saying I don't return
  • 00:03:56 a response I just did something in this
  • 00:03:59 case I locked something you continue
  • 00:04:01 doing your work so let's use Morgan and
  • 00:04:05 let's use it before we handle our
  • 00:04:08 requests with our routes by simply
  • 00:04:10 saying app use and then use some more
  • 00:04:13 again as a function and pass death here
  • 00:04:17 that's the format we want to use for the
  • 00:04:19 output now with that let's rerun NPM
  • 00:04:23 start to restart node Mon and if I now
  • 00:04:27 again send a request here it looked as
  • 00:04:29 before but you see now in a terminal we
  • 00:04:32 get this extra log seeing that we got a
  • 00:04:34 get request and how long it took and so
  • 00:04:37 on so that's really nice additionally I
  • 00:04:40 now want to handle errors keep in mind
  • 00:04:43 if we send a request to some invalid ID
  • 00:04:46 or with some invalid HTTP word we get
  • 00:04:49 back this default error HTML page and I
  • 00:04:52 want to send back JSON instead now error
  • 00:04:55 handling is really nice in
  • 00:04:58 set up here keep in mind that we have
  • 00:05:00 here our middleware which forwards
  • 00:05:02 requests to products and orders files
  • 00:05:06 where we then have to router on the
  • 00:05:08 apprehend that means if we make it past
  • 00:05:11 these two middlewares
  • 00:05:13 none of the routes set up an IVA of the
  • 00:05:16 two files were suited to handle the
  • 00:05:18 incoming requests hence we can handle
  • 00:05:21 errors by simply catching all requests
  • 00:05:24 that make it past these two requests
  • 00:05:26 here these two middlewares I should say
  • 00:05:28 so we can something use the app object
  • 00:05:31 and now use and no longer add a filter
  • 00:05:35 like slash something but simply say I
  • 00:05:38 want to handle every request that
  • 00:05:41 reaches this line because if you reach
  • 00:05:43 that line it means no route in one of
  • 00:05:46 these two files was able to handle the
  • 00:05:48 request so here in this middle of where
  • 00:05:51 I again have my request response and the
  • 00:05:53 next function and now I simply want to
  • 00:05:57 return an error here so I will create a
  • 00:06:00 new constant error and create a new
  • 00:06:03 error here the error object is available
  • 00:06:06 by default you don't need to import it
  • 00:06:08 or anything like that and here I want to
  • 00:06:12 output not found as a error text I will
  • 00:06:17 also set a error status code excuse me
  • 00:06:21 that should be error so that error
  • 00:06:23 object is provided by no chase and I can
  • 00:06:26 set a status code of 404 because here we
  • 00:06:30 get here if we have an error because we
  • 00:06:32 didn't find a fitting route which is the
  • 00:06:34 definition of a 404 error then I will
  • 00:06:37 actually execute this next method and
  • 00:06:39 pass my error along with it this will
  • 00:06:43 now forward the request but forward this
  • 00:06:47 error request here instead of the
  • 00:06:50 original one essentially now add another
  • 00:06:53 middleware here where I also get my
  • 00:06:57 request response and next but I get a
  • 00:06:59 separate first argument which actually
  • 00:07:02 is my error and this here will handle
  • 00:07:06 all kinds of errors like the error we
  • 00:07:09 create here and we for
  • 00:07:11 word or and that is why I chose this
  • 00:07:13 setup errors thrown from anywhere else
  • 00:07:16 in this application this shouldn't
  • 00:07:19 really be able to happen yet but later
  • 00:07:21 when we add a database for example and
  • 00:07:24 when we have operations doing work on
  • 00:07:27 the database these operations could fail
  • 00:07:29 and we then want to return a 500 error
  • 00:07:33 now if these operations fail they will
  • 00:07:35 directly throw an error so we don't make
  • 00:07:38 it into this first middleware but since
  • 00:07:41 they throw an error this middleware here
  • 00:07:44 would be triggered and it would handle
  • 00:07:47 this error or get this error so here we
  • 00:07:49 can set a status code on the response we
  • 00:07:52 eventually want to send back which is
  • 00:07:54 either the status code the error has
  • 00:07:57 like it has if we created our 400 error
  • 00:08:00 404 error or we assign a 500 error code
  • 00:08:05 for all other kinds of errors and then
  • 00:08:08 we can simply return some JSON data here
  • 00:08:11 and we could have changed that as I did
  • 00:08:13 in the router setup so that would have
  • 00:08:15 worked too and there I want to send an
  • 00:08:18 error object which maybe should have a
  • 00:08:21 message property and this setup is
  • 00:08:24 totally up to you set it up as you want
  • 00:08:26 and there I will pass on my error
  • 00:08:30 message like the message this should
  • 00:08:34 also be error by the way the a message
  • 00:08:36 of the error we get as a first argument
  • 00:08:38 here the message will automatically be
  • 00:08:40 not found and for other errors
  • 00:08:44 whoops fix the typo for our errors these
  • 00:08:47 typically also have a message property
  • 00:08:49 it's kind of what most errors have you
  • 00:08:52 can pretty much rely on them having a
  • 00:08:54 message object a message property and
  • 00:08:57 now we will return this so let's try
  • 00:09:01 this out let's save this and no daman
  • 00:09:03 will restart and now let's again send an
  • 00:09:06 invalid request now you see we get back
  • 00:09:10 a method and our answer here error
  • 00:09:14 status is not a function it nicely
  • 00:09:16 proves that the automatically thrown
  • 00:09:18 error has a message property because
  • 00:09:21 that's not our own error and I did
  • 00:09:23 indeed
  • 00:09:24 is up here we should assign an error
  • 00:09:26 status property of 404 not a method so
  • 00:09:30 now let's try this again and now we get
  • 00:09:33 not found which again is our custom
  • 00:09:36 message this one and so I accidentally
  • 00:09:40 but it's also kind of good I guess
  • 00:09:41 proved that though our custom 404 and
  • 00:09:46 ler SD I handle all other kinds of
  • 00:09:49 errors like my error with the unknown
  • 00:09:51 function here both work and with that we
  • 00:09:55 got automatic reloading
  • 00:09:56 we got default logging and we got error
  • 00:09:59 handling which is a great improvement to
  • 00:10:01 our project with that let's leave it as
  • 00:10:05 this and let's go back into our project
  • 00:10:08 and make sure that we add more useful
  • 00:10:11 functionalities to it in the next videos