{"id":2104,"date":"2022-08-30T15:22:05","date_gmt":"2022-08-30T15:22:05","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/12\/26\/wrapping-thrown-errors-so-they-dont-crash-the-node-webserver-node-mongodb-native-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:22:05","modified_gmt":"2022-08-30T15:22:05","slug":"wrapping-thrown-errors-so-they-dont-crash-the-node-webserver-node-mongodb-native-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/wrapping-thrown-errors-so-they-dont-crash-the-node-webserver-node-mongodb-native-collection-of-common-programming-errors\/","title":{"rendered":"Wrapping thrown errors so they don&#39;t crash the node webserver (node-mongodb-native)-Collection of common programming errors"},"content":{"rendered":"<p>Simplified code&#8230; but the basic scenario is I&#8217;m doing a findOne query with Mongo to lookup a user, but if the user doesn&#8217;t exist it throws an error that crashes the entire webserver. Can someone point me in the right direction for correctly wrapping these errors so they don&#8217;t bring everything down?<\/p>\n<p>The Route:<\/p>\n<pre><code>server.get('\/v1\/user\/:token', function(req,res){\n    console.log(\"user endpoint hit\");\n    var user = users.findOne({token:req.params.token}, function(err,user){\n        if (user) {\n            res.json({token:user.token,credits:user.credits,subscribed:user.subscribed,searches:user.searches});\n        } else {\n            console.log(\"DB error in lookup user\");\n            throw new DBError(\"Error looking up user in get endpoint\");\n        }\n    });\n});\n<\/code><\/pre>\n<p>The DBError declaration:<\/p>\n<pre><code>function DBError(msg) {\n    this.name = \"DBError\";\n    console.log(\"DBError \" + msg);\n    Error.call(this,msg);\n    Error.captureStackTrace(this, arguments.callee);\n}\n<\/code><\/pre>\n<p>And here is the chunk that handles errors:<\/p>\n<pre><code>server.error(function(err, req, res, next){\n    if (err instanceof NotFound) {\n        res.send(404,{error: \"404 Not Found\"});\n    }\n    else if (err instanceof DBError) {\n        res.send(400, {error: \"Database error\"});\n    } else {\n        res.send(500,{error:\"500 internal error\"});\n    }\n});\n<\/code><\/pre>\n<p>Now when I run my unit tests here is the stacktrace, which then ends the server process (not ideal!):<\/p>\n<pre><code>user endpoint hit\nDB error in lookup user\nDBError Error looking up user in get endpoint\n\n\/Users\/msencenb\/Development\/nodeProjects\/reversePhoneLookup\/server\/app\/node_modules\/mongodb\/lib\/mongodb\/connection\/server.js:563\n        throw err;\n              ^\n[object Object]\n<\/code><\/pre>\n<ol>\n<li>\n<p>In general you just don&#8217;t throw errors. Errors are supposed to shut down the process\/worker when something goes terribly wrong. I wouldn&#8217;t consider not finding a user in your code above to be something that went terribly wrong, but sure depending on your specific case that might be something that&#8217;s not supposed to ever happen.<\/p>\n<p>When you need to handle errors though, the most widespread way [citation needed] is to pass it as the first argument in the callback (as you can see in the callback for <code>findOne()<\/code>). In express it&#8217;s done using the third parameter in a middleware, known as <code>next<\/code>, and an error handler. For example like this:<\/p>\n<p>Your route:<\/p>\n<pre><code>server.get('\/v1\/user\/:token', function(req,res,next){\n    console.log(\"user endpoint hit\");\n    var user = users.findOne({token:req.params.token}, function(err,user){\n        if (user) {\n            res.json({token:user.token,credits:user.credits,subscribed:user.subscribed,searches:user.searches});\n        } else {\n            next(new DBError(\"Error looking up user in get endpoint\"));\n        }\n    });\n});\n<\/code><\/pre>\n<p>Specify an error handler where you use your middleware:<\/p>\n<pre><code>app.use(function(err, req, res, next){\n  \/\/ This will handle all errors sent through next()\n  console.error(err.stack);\n  res.send(500, 'Something broke!');\n});\n<\/code><\/pre>\n<p>Also you might want to have a look at domains in node. That page also touches how to properly respond to errors.<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-12-26 03:15:31. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>Simplified code&#8230; but the basic scenario is I&#8217;m doing a findOne query with Mongo to lookup a user, but if the user doesn&#8217;t exist it throws an error that crashes the entire webserver. Can someone point me in the right direction for correctly wrapping these errors so they don&#8217;t bring everything down? The Route: server.get(&#8216;\/v1\/user\/:token&#8217;, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2104","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2104","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=2104"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2104\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=2104"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=2104"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=2104"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}