{"id":2695,"date":"2018-11-01T16:55:31","date_gmt":"2018-11-01T14:55:31","guid":{"rendered":"http:\/\/hasselba.ch\/blog\/?p=2695"},"modified":"2018-11-01T17:00:28","modified_gmt":"2018-11-01T15:00:28","slug":"node-js-domino-db-docker-4-error-handling","status":"publish","type":"post","link":"https:\/\/hasselba.ch\/blog\/?p=2695","title":{"rendered":"node.js, domino-db &#038; Docker (4): Error Handling"},"content":{"rendered":"<p>When we started our express application and accessed it in the browser, an error raised on the console and no response was sent back to the browser. The reason for this behaviour is that the database connection is not correctly configured, and the request from our application fails.<\/p>\n<p>For a better understanding I have refactored the code to &#8222;old-school&#8220; Javascript. The functions are called in a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Guide\/Using_promises\" target=\"_blank\" rel=\"noopener\">promise<\/a> chain.<\/p>\n<pre><code>router.get('\/', function(req, res, next) {\r\n  useServer(serverConfig)\r\n  .then(\r\n      function(server){\r\n        return server.useDatabase(databaseConfig)\r\n      })\r\n  .then(\r\n      function(database){\r\n        return database.bulkCreateDocuments(createOptions)\r\n      })\r\n  .then(\r\n      function(response){\r\n        const unids = response.documents.map(doc =&gt; doc['@unid']);\r\n        res.render('index', { title: 'Express', result: `Documents created: ${unids}` });\r\n      }\r\n  );\r\n});<\/code><\/pre>\n<p>1. The <em>get<\/em> method of the <em>router<\/em> calls the anonymous function (2nd parameter).<\/p>\n<p>2. The chain starts: This function calls the <em>useServer<\/em> method of the domino-db package with the <em>serverConfig<\/em>.<\/p>\n<p>3. If everything is OK, the next method in the chain is called with the <em>server<\/em> object (the result of the previous operation).<\/p>\n<p>4. If everything is OK, the next method in the chain is called with the <em>database<\/em> object.<\/p>\n<p>5. If everything is OK, the next method in the chain is called with the <em>result<\/em> object.<\/p>\n<p>Promises have two callback functions: The first parameter is always the &#8222;success&#8220; callback, and the second the &#8222;error&#8220; callback. But we are not using a second parameter, because this allows us to use a <em>catch<\/em> function at the end of our chain:<\/p>\n<pre><code>router.get('\/', function(req, res, next) {\r\n  useServer(serverConfig)\r\n  .then(\r\n      ... )\r\n  .then(\r\n      ... )\r\n  .then(\r\n      ... )\r\n  .catch(\r\n    function(error) {\r\n      console.log(error);\r\n      res.render('error', { title: 'Error', error });\r\n    }\r\n  );\r\n});<\/code><\/pre>\n<p>The catch block handles every error in our chain, and renders the view &#8218;<em>error<\/em>&#8218; with the reason of the failure.<\/p>\n<p>If we now restart our application, the error is displayed to the end user with a stacktrace:<\/p>\n<p><a href=\"https:\/\/hasselba.ch\/blog\/wp-content\/uploads\/2018\/11\/gRPC-error.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2697\" src=\"https:\/\/hasselba.ch\/blog\/wp-content\/uploads\/2018\/11\/gRPC-error.png\" alt=\"\" width=\"2298\" height=\"426\" srcset=\"https:\/\/hasselba.ch\/blog\/wp-content\/uploads\/2018\/11\/gRPC-error.png 2298w, https:\/\/hasselba.ch\/blog\/wp-content\/uploads\/2018\/11\/gRPC-error-300x56.png 300w, https:\/\/hasselba.ch\/blog\/wp-content\/uploads\/2018\/11\/gRPC-error-768x142.png 768w, https:\/\/hasselba.ch\/blog\/wp-content\/uploads\/2018\/11\/gRPC-error-1024x190.png 1024w\" sizes=\"auto, (max-width: 2298px) 100vw, 2298px\" \/><\/a><\/p>\n<p>And now, we are refactoring the code using the <a href=\"https:\/\/codeburst.io\/javascript-arrow-functions-for-beginners-926947fc0cdc\" target=\"_blank\" rel=\"noopener\">arrow syntax<\/a>:<\/p>\n<pre><code>router.get('\/', (req, res) =&gt; {\r\n  useServer(serverConfig)\r\n  .then(server =&gt; server.useDatabase(databaseConfig))\r\n  .then(database =&gt; database.bulkCreateDocuments(createOptions))\r\n  .then(response =&gt; {\r\n        const unids = response.documents.map(doc =&gt; doc['@unid']);\r\n        res.render('index', { title: 'Express', result: `Documents created: ${unids}` });\r\n  })\r\n  .catch(error =&gt; {\r\n      console.log(error);\r\n      res.render('error', { title: 'Error', error });\r\n    }\r\n  );\r\n});<\/code><\/pre>\n<p>A lot shorter, isn&#8217;t it?<\/p>\n<p>At the end, we are using <a href=\"https:\/\/ponyfoo.com\/articles\/understanding-javascript-async-await\" target=\"_blank\" rel=\"noopener\">async\/await<\/a> syntax to shorten the promise chain too:<\/p>\n<pre><code>router.get('\/', (req, res) =&gt; {\r\n  useServer(serverConfig).then(\r\n    async server =&gt; {\r\n      const database = await server.useDatabase(databaseConfig);\r\n      const response = await database.bulkCreateDocuments(createOptions);\r\n      const unids = response.documents.map(doc =&gt; doc['@unid']);\r\n      res.render('index', { title: 'Express', result: `Documents created: ${unids}` });\r\n    }\r\n  ).catch(error =&gt; {\r\n      console.log(error);\r\n      res.render('error', { title: 'Error', error });\r\n  });\r\n});<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>When we started our express application and accessed it in the browser, an error raised on the console and no response was sent back to the browser. The reason for this behaviour is that the database connection is not correctly &hellip; <a href=\"https:\/\/hasselba.ch\/blog\/?p=2695\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,134,131],"tags":[7,138,133,135,132],"class_list":["post-2695","post","type-post","status-publish","format-standard","hentry","category-javascript","category-jsx","category-node-js","tag-domino","tag-domino-db","tag-express","tag-jsx","tag-node-js"],"_links":{"self":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2695","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2695"}],"version-history":[{"count":4,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2695\/revisions"}],"predecessor-version":[{"id":2701,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2695\/revisions\/2701"}],"wp:attachment":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2695"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2695"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2695"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}