{"id":209,"date":"2018-11-25T08:29:24","date_gmt":"2018-11-25T02:59:24","guid":{"rendered":"http:\/\/uitutorials.in\/wp\/?p=209"},"modified":"2021-04-29T17:32:06","modified_gmt":"2021-04-29T12:02:06","slug":"error-handling-middleware-express-js-in-node","status":"publish","type":"post","link":"https:\/\/uitutorials.in\/wp\/error-handling-middleware-express-js-in-node\/","title":{"rendered":"Error &#8211; handling Middleware Express JS in Node"},"content":{"rendered":"<h2>Error-handling middleware<\/h2>\n<p><strong>Basic Syntax <\/strong><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">let convertRupees = (dollar) =&gt; {\r\n\tif(typeof dollar === 'number') {\r\n\t\treturn dollar * 69\r\n\t} else {\r\n\t\tthrow Error ('Amount must be in number')\r\n\t}\r\n}\r\n\r\ntry {\r\n\tconsole.log(convertRupees('one'));\r\n} catch (error){\r\n\tconsole.error(error)\r\n}\r\n\r\nconsole.log('If we used try...catch..This line will show even if error raised ')\r\n<\/code><\/pre>\n<p>An Express application can use any of the below mentioned types of middleware:<\/p>\n<ul>\n<li>\n<p>Application-level middleware : app.use<\/p>\n<\/li>\n<li>\n<p>Router-level middleware : router.use<\/p>\n<\/li>\n<li>\n<p>Error handling middleware app.use(err,req,res,next)<\/p>\n<\/li>\n<li>\n<p>Built-in middleware : express.static,express.json,express.urlencoded<\/p>\n<\/li>\n<li>\n<p>Third-party middleware : bodyparser,cookieparser<\/p>\n<\/li>\n<\/ul>\n<p>Error-handling middleware will have four arguments, the forth next will identify it as an error-handling middleware. the signature is (err, req, res, next). Express error handling middle-ware is very helpful in catching globally occurring errors without worrying about the Server to crash.<\/p>\n<h3>Example Without Error-handling Middleware<\/h3>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\r\nvar express = require('express');\r\nvar app = express();\r\n\r\napp.use(function(req,res,next) {\r\n  console.log(\"In second route\");\r\n  next(); \/\/ go to next route.\r\n});\r\n\r\napp.get('\/', function(req,res){\r\n  res.send('Welcome NodeJs !');\r\n})\r\nserver = app.listen(3000, function() {\r\n      console.log('Listenint Port : 3000 ');\r\n  });\r\n<\/code><\/pre>\n<h3>Example Error-handling Middleware<\/h3>\n<p>To generate the run-time error, we will throw random error and see whether it catches it or not.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\r\nvar express = require('express');\r\nvar app = express();\r\n\r\napp.use(function(req,res,next) {\r\n  console.log(\"In second route\");\r\n  next(); \/\/ go to next route.\r\n});\r\n\r\napp.get('\/', function(req,res){\r\n  throw new Error(); \/\/ Express will catch this on its own.\r\n  res.send('Welcome NodeJs !');\r\n})\r\napp.use(function(err,req,res,next) {\r\n  console.log(\"Error happens\",err.stack);\r\n  res.status(500).send({\"Error Happen in the Request : \" : err.stack});\r\n});\r\nserver = app.listen(3000, function() {\r\n      console.log('Listenint Port : 3000 ');\r\n  });\r\n <\/code><\/pre>\n<h3>Third-party Middlewares<\/h3>\n<p>In some cases we will be adding some extra features to our backend<\/p>\n<p>Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level<\/p>\n<p>Example : body-parser <\/p>\n<p>This third party middleware will Parse incoming request bodies in a middleware before your handlers, available under the req.body property.<\/p>\n<p>To install run the below command <\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\"> npm install body-parser <\/code><\/pre>\n<p>Example : app.js<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\"> \r\nvar express = require('express');\r\nvar  bodyParser = require('body-parser');\r\nvar app = express();\r\n\r\napp.use(bodyParser.urlencoded({extended:false}))\r\n\r\napp.use(bodyParser.json())\r\n\r\napp.post('\/save',(req,res)=&gt;{\r\n  res.json({\r\n    \"status\":true,\r\n    \"payload\":req.body\r\n  })\r\n})\r\n          \r\nvar server = app.listen(3000, function() {\r\n      console.log('Listenint Port : 3000 ');\r\n  });\r\n<\/code><\/pre>\n<p>Run the command in node terminal<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">node app.js<\/code><\/pre>\n<p>And browse the path in postman : &#8220;http:\/\/localhost:3000\/save&#8221; <\/p>\n<p>Output<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\r\n{\r\n    \"status\": true,\r\n    \"payload\": {}\r\n}\r\n<\/code><\/pre>\n<h3>Handling 404 errors with Router middleware <\/h3>\n<p>when a route does not match with any handler then it will throw 404 Error. To do this we will put a middle-ware at the end of all routes, it will be executed when none of the routes match.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\r\n\r\nvar express = require(\"express\");\r\nvar app = express();\r\n\r\n\/\/Creating Router() object\r\n\r\nvar router = express.Router();\r\n\r\n\/\/ Router middleware, mentioned it before defining routes.\r\n\r\nrouter.use(function (req, res, next) {\r\n    console.log(\"\/\" + req.method);\r\n    next();\r\n});\r\n\r\nrouter.use(\"\/user\/:id\", function (req, res, next) {\r\n    console.log('Passed Value : ' + req.params.id)\r\n    if (req.params.id == 0) {\r\n        res.json({ \"message\": \"Pass ID other than 0\" });\r\n    }\r\n    else next();\r\n});\r\n\r\n\/\/ Provide all routes here, this is for Home page.\r\n\r\nrouter.get(\"\/\", function (req, res) {\r\n    res.json({ \"message\": \"Welcome Express Router\" });\r\n});\r\n\r\nrouter.get(\"\/user\/:id\", function (req, res) {\r\n    res.json({ \"message\": \"Express Router with Param \" + req.params.id });\r\n});\r\n\r\n\/\/ Handle 404 error. \r\n\/\/ The last middleware.\r\napp.use(\"*\", function (req, res) {\r\n    res.status(404).send('404');\r\n});\r\n\r\n\r\n\/\/ Tell express to use this router with \/api before ex - http:\/\/localhost:3000\/api .\r\napp.use(\"\/api\", router);\r\n\r\n\/\/ Listen to this Port\r\n\r\napp.listen(3000, function () {\r\n    console.log(\"Listening Port : 3000\");\r\n});\r\n<\/p>\r\n<\/code><\/pre>\n<h2>Error Handling<\/h2>\n<p>We&#8217;re distinguishing between errors in development  and in production.  When we&#8217;re in production, we send the error  using this function here,  which will then send as many details as possible  to the client,  so that we really get all the information  in order to get rid of the bug.  If it&#8217;s a programming error,  or if it&#8217;s an operational error,  then we still really want to see anything that&#8217;s going on.<br \/>\nWhen we&#8217;re in production,  which is arguably the most important part  of our application, then we distinguish  between operational errors,  so errors that we know and trust,  and to other errors, that might be kind of unexpected.  <\/p>\n<p>If the error is operational, so for example<br \/>\n1.the user  tried to access a route that doesn&#8217;t exist,<br \/>\n2.or tried to input invalid data<br \/>\nall of these are operational errors.Then we can send appropriate error messages,  for the client to know what went wrong.<\/p>\n<p>On the other hand, we have these unknown errors\/unexpected errors<br \/>\nFor example : Coming from MongoDB, which we do not mark as operational.  In this case, they would right now simply be handled  using this generic error message here.  For example, a validation error.  Right now, that&#8217;s an error that&#8217;s coming from MongoDB  and not from our own app error class.  We do not create these errors by ourselves.  Again, they are right now not marked as operational,  but we of course need to mark them as operational  so that we can then send the appropriate error message  back to the client.  In the example that I was just mentioning,  that the input data is invalid.  There are two or three other errors that we need to mark  as operational ourselves.  So we will do that  down here.  So in this else block,  we will do that over the next couple of lectures.<\/p>\n<h3>Three type of Errors in MongoDB : 400 &#8211; Bad Request<\/h3>\n<p>1. Invalid ID (We have to show it as Operational Errors)  &#8211; (error.name === &#8216;CastError&#8217;)<br \/>\n2. Duplicate Name In DB (error.code == 1100)<br \/>\n3. ValidationError [Max Value] &#8211; (error.name == &#8216;ValidationError&#8217;)<\/p>\n<p>500 &#8211; Internal Server Error<\/p>\n<p>Steps:<br \/>\n=======<\/p>\n<h3>We can directly create the middleware in &#8220;index.js&#8221;<\/h3>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">app.all('*', (req, res, next) => {\r\n  \r\n  res.status(404).json({\r\n    status: 'fail',\r\n    message: `Can't Find URL${req.originalUrl} on the server`\r\n  })\r\n  \r\n  \/\/ const err = new Error(`Can't find ${req.originalUrl} on this server !`)\r\n  \/\/ err.status = 'fail';\r\n  \/\/ err.statusCode = 404;\r\n  \/\/ next(err);\r\n\r\n  \r\n})\r\n\r\napp.use((err, req, res, next)=> {\r\n  err.statusCode = err.statusCode || 500;\r\n  err.status = err.status || 'error';\r\n\r\n  res.status(err.statusCode).json({\r\n    status: err.status,\r\n    message: err.message\r\n  });\r\n})\r\n<\/code><\/pre>\n<h3>2. we&#8217;re gonna build a couple of different functions for handling with different types of errors,and so I want all of these functions to be all in the same file, all right ? Controlling errors (appController.js)<\/h3>\n<p><strong># move the middleware from index.js to appController.js<\/strong><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">module.exports = (err, req, res, next)=> {\r\n  err.statusCode = err.statusCode || 500;\r\n  err.status = err.status || 'error';\r\n\r\n  res.status(err.statusCode).json({\r\n    status: err.status,\r\n    message: err.message\r\n  });\r\n}<\/code><\/pre>\n<h3>4. import &#8220;appController&#8221; into the &#8220;index.js&#8221; file<\/h3>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">const globalErrorHandler = '.\/appController.js'\r\n\r\napp.all('*', (req, res, next) => {\r\n  next(new AppError(`Can't Find URL${req.originalUrl} on the server`, 404));\r\n})\r\napp.use(globalErrorHandler)<\/code><\/pre>\n<h3>3. Add the AppError Class<\/h3>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">class AppError extends Error {\r\n    constructor(message, statusCode){\r\n        super(message);\r\n        this.statusCode = statusCode;\r\n        this.status = `${statusCode}`.startsWith('4') ? 'fail':'error';\r\n        this.isOperational = true;\r\n\r\n        Error.captureStackTrace(this, this.constructor);\r\n    }\r\n}\r\n\r\nmodule.exports = AppError;<\/code><\/pre>\n<h3>4. import &#8220;AppError&#8221; into the &#8220;index.js&#8221; file<\/h3>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">app.all('*', (req, res, next) => {\r\n  next(new AppError(`Can't Find URL${req.originalUrl} on the server`, 404));\r\n})<\/code><\/pre>\n<h3>5.Modify the async await functions<\/h3>\n<p># async function return promises so receive the error in catch part.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">const catchAsync = fn => {\r\n\treturn (req,res,next) => {\r\n\t\tfn(req, res, next).catch(err=> next(err))\r\n\t}\t\r\n}\r\n\r\nexport.createTour = catchAsync(async(req,res,next) => {\r\n\tconst newTour = await Tour.create(req.body)\r\n\t\r\n\tres.statu(201).json({\r\n\t\tstatus: 'Success',\r\n\t\tdata: {tour: newTour}\r\n\t})\r\n})<\/code><\/pre>\n<h3>6. Move the catchAsync to new file <\/h3>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">module.exports =  catchAsync = fn => {\r\n\treturn (req,res,next) => {\r\n\t\tfn(req, res, next).catch(err=> next(err))\r\n\t}\t\r\n}<\/code><\/pre>\n<h3>7. Import catchAsync into controller.js and use it<\/h3>\n<pre class=\"line-numbers\"><code class=\"language-javascript\"><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Error-handling middleware Basic Syntax let convertRupees = (dollar) =&gt; { if(typeof dollar === &#8216;number&#8217;) { return dollar * 69 } else { throw Error (&#8216;Amount must be in number&#8217;) } } try { console.log(convertRupees(&#8216;one&#8217;)); } catch (error){ console.error(error) } console.log(&#8216;If we used try&#8230;catch..This line will show even if error raised<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,1],"tags":[37,35,34],"class_list":["post-209","post","type-post","status-publish","format-standard","hentry","category-mongodb","category-nodejs","tag-error-handling-middleware","tag-express-js-middleware","tag-express-middleware","ct-col-2"],"_links":{"self":[{"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/posts\/209","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/comments?post=209"}],"version-history":[{"count":6,"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/posts\/209\/revisions"}],"predecessor-version":[{"id":2240,"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/posts\/209\/revisions\/2240"}],"wp:attachment":[{"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/media?parent=209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/categories?post=209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/uitutorials.in\/wp\/wp-json\/wp\/v2\/tags?post=209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}