{"id":618,"date":"2014-06-03T12:22:00","date_gmt":"2014-06-03T12:22:00","guid":{"rendered":"https:\/\/gosqeng.test\/?p=618"},"modified":"2019-11-28T12:09:37","modified_gmt":"2019-11-28T12:09:37","slug":"error-handling-using-domains-node-js","status":"publish","type":"post","link":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js","title":{"rendered":"Crash safety using domains in Node.js"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png\" alt=\"crash_safely_using_domains_in_node.js\"><\/p>\n<p>In a <a href=\"https:\/\/www.gosquared.com\/blog\/node-js-error-handling-callbacks-vs-promises\" target=\"_blank\" rel=\"noopener noreferrer\">previous post<\/a> about handling errors in Node.js programs, I took a look at how different flow control styles handle errors. I wanted to revisit the topic of error handling in a little more detail, and take a deeper look at an important error handling tool in Node.js: <a href=\"http:\/\/nodejs.org\/docs\/v0.10.28\/api\/domain.html\" target=\"_blank\" rel=\"noopener noreferrer\">domains<\/a>. We&#8217;ll see how domains work, why you would use them, and how to go about it.<\/p>\n<p>Before we start, I want to recommend a useful <a href=\"http:\/\/www.joyent.com\/developers\/node\/design\/errors\" target=\"_blank\" rel=\"noopener noreferrer\">article about error handling<\/a> in Node by Joyent. I found it in their &#8220;Production Practises&#8221; documentation and it explains in good detail all of the essential information about errors in Node, such as the different kinds of error in a node program and the scenarios in which you might encounter them. It acts as a great primer to the material in this article, so take some time to absorb it and carry on with this after.<\/p>\n<h2>Why should I care about domains?<\/h2>\n<p><a href=\"http:\/\/nodejs.org\/docs\/v0.10.28\/api\/domain.html\" target=\"_blank\" rel=\"noopener noreferrer\">Domains<\/a> were introduced in Node.js v0.8 as a way of dealing with unhandled &#8216;error&#8217; events, uncaught exceptions,\u00a0and even errors passed to callbacks via <a href=\"http:\/\/nodejs.org\/docs\/v0.10.28\/api\/domain.html#domain_domain_intercept_callback\" target=\"_blank\" rel=\"noopener noreferrer\"><code>domain.intercept()<\/code><\/a>.<\/p>\n<p>The general idea of domains is that if an error is not handled and is allowed to bubble up the stack all the way out of your program reaching\u00a0node itself, you can get Node.js to notify your domain about the error instead of freaking out and immediately exiting the process. The domain is set up by your program, allowing your program to decide what to do with an un-handled error in a controlled manner. Usually, the best course of action is to gracefully shut down your program and exit the process at an appropriate time.<\/p>\n<p>A good example for why we should use domains is for a Node.js HTTP server. Imagine we have a simple HTTP server which invokes your program&#8217;s callback to handle each incoming request:<\/p>\n<pre><code class=\"language-javascript\">\nvar http = require('http');\nhttp.createServer(function(req, res) {\n  \/\/ On 10% of requests this code will run and throw an exception\n  if (Math.random() &gt; 0.9) {\n    woops.thisWillThrow();\n  }\n}).listen(8000);\n\n<\/code><\/pre>\n<p>You can see there is a mistake in the <code class=\"language-javascript\">if<\/code> block. If one of the requests try to run that code, an exception is thrown due to a <span style=\"color: #ff0000;\"><code>ReferenceError<\/code><\/span> from the undefined <span style=\"color: #3366ff;\"><code>woops<\/code><\/span> object.<\/p>\n<p>In the example of a web server, we will likely be serving many clients concurrently, and if an exception happens during a request from one client, it will crash the server and abruptly hang up on that client as well as all the other clients! This can lead to all kinds of nasty consequences,\u00a0but at the very least it is damaging to our user&#8217;s experience.<\/p>\n<p>So, here&#8217;s where we would use a domain. If we have a domain active, Node.js will tell that domain when an exception occurs. Our domain can then perform the necessary steps to gracefully shut down the program. In the case of our server program, we would want to:<\/p>\n<ol>\n<li>Close the server to stop accepting new connections. Hopefully this will also signal a terminating proxy (such as a load balancer) to stop routing requests to this process.<\/li>\n<li>Wait for existing connections to finish and close normally.<\/li>\n<li>Only exit the process once all clients have finished and disconnected happily.<\/li>\n<li>Failsafe: before starting the shutdown, it&#8217;s advisable to set an exit time limit. If the shutdown hangs or takes too long, something else is probably wrong so exit the process anyway.<\/li>\n<\/ol>\n<h2>What is a domain, exactly?<\/h2>\n<p>A domain is an <a href=\"http:\/\/nodejs.org\/api\/events.html#events_class_events_eventemitter\" target=\"_blank\" rel=\"noopener noreferrer\">EventEmitter<\/a> object which, when &#8220;entered&#8221;, is accessible globally via <code class=\"language-javascript\">process.domain<\/code> and <code class=\"language-javascript\">require('domain').active<\/code>. Multiple domains can exist in the domain stack, which is simply an array internally in Node holding all domains in the order they were created. Only one domain can be active on the process at a time, and is only active when it is &#8220;entered&#8221;. This is so that when Node.js is running code, it knows which domain should be notified about any unhandled errors that might occur.<\/p>\n<h2>How to use domains<\/h2>\n<p>By \u00a0attaching a listener to the domain&#8217;s <code class=\"language-javascript\">'error'<\/code> event, you control what happens when the domain is notified of an error:<\/p>\n<pre><code class=\"language-javascript\">\nvar domain = require('domain');\nvar d = domain.create();\n\/\/ Domain emits 'error' when it's given an unhandled error\nd.on('error', function(err) {\n  console.log(err.stack);\n\u00a0\/\/ Our handler should deal with the error in an appropriate way\n});\n\n\/\/ Enter this domain\nd.run(function() {\n  \/\/ If an un-handled error originates from here, process.domain will handle it\n  console.log(process.domain === d); \/\/ true\n});\n\n\/\/ domain has now exited. Any errors in code past this point will not be caught.\n<\/code><\/pre>\n<p>In this example, we&#8217;re setting up a domain with an &#8216;error&#8217; handler. We call <code class=\"language-javascript\">d.run<\/code> to enter the domain. The domain will be active while the code in the callback runs. After the function completes, the domain is exited. We&#8217;re not waiting on any asynchronous I\/O here so the code in this example runs synchronously in the context of the domain.<\/p>\n<p>What happens when we need to run a callback asynchronously, where the callback could be called after the domain has exited? How do we still ensure the domain will capture unhandled errors exuded by these callbacks? Node has an in-built method of doing this: domain binding.<\/p>\n<h3>Implicit\/explicit binding on event emitters and timers<\/h3>\n<p><a href=\"http:\/\/nodejs.org\/docs\/v0.10.28\/api\/domain.html#domain_implicit_binding\" target=\"_blank\" rel=\"noopener noreferrer\">The documentation<\/a> explains implicit and explicit binding.<\/p>\n<p>Asynchronous callbacks are called\u00a0by\u00a0events and timers in Node. When you have a callback which is waiting for the result of a particular I\/O operation, the callback will be called on a different tick of the event loop to the one in which the I\/O operation was queued, and after the domain has exited.<\/p>\n<p>To make sure their\u00a0callbacks\u00a0are called\u00a0in the context of\u00a0a domain,\u00a0event emitters and timers are\u00a0implicitly bound to a domain if it is active when they are created. This is what is meant by Implicit binding.<\/p>\n<p>It is possible to re-assign the event emitter\u00a0or timer to another domain using\u00a0<a href=\"http:\/\/nodejs.org\/docs\/v0.10.28\/api\/domain.html#domain_explicit_binding\" target=\"_blank\" rel=\"noopener noreferrer\">Explicit binding<\/a>. Likewise, the explicitly bound domain will be active while the callback is run.\u00a0\u00a0You can see this happening in <a href=\"https:\/\/github.com\/joyent\/node\/blob\/cc56c62ed879ad4f93b1fdab3235c43e60f48b7e\/lib\/events.js#L85\" target=\"_blank\" rel=\"noopener noreferrer\">events.js<\/a>.<\/p>\n<p>Let&#8217;s see what happens with an event emitter:<\/p>\n<pre><code class=\"language-javascript\">var EventEmitter = require('events').EventEmitter;\nvar domain       = require('domain');\n\n\/\/ Create 2 domains\nvar d1 = domain.create();\nvar d2 = domain.create();\n\n\/\/ Enter the first domain\nd1.run(function() {\n  \/\/ This emitter is implicitly bound to d1\n  \/\/ because it is created while process.domain === d1\n  var implicitEmitter = new EventEmitter();\n  implicitEmitter.on('someEvent', function() {\n    console.log(process.domain === d1); \/\/ true\n  });\n\n  implicitEmitter.emit('someEvent');\n\n  \/\/ Explicitly bind this emitter to another domain\n  var explicitEmitter = new EventEmitter();\n  d2.add(explicitEmitter);\n\n  explicitEmitter.on('someEvent', function() {\n    console.log(process.domain === d2); \/\/ true\n  });\n\n  explicitEmitter.emit('someEvent');\n});\n<\/code><\/pre>\n<p>So, let&#8217;s recap on what&#8217;s happening here.<\/p>\n<p>Whenever an event is emitted on the EventEmitter object, the EventEmitter enters its bound domain immediately\u00a0<em>before<\/em> the event listener is called, and exits the domain straight afterwards. This ensures that any error generated by the event listener will be routed to the EventEmitter&#8217;s domain, and <em>not<\/em> the domain that might have been active before the event was fired.<\/p>\n<p>This is one of the confusing aspects of domains: they exist globally, but event emitters and timers switch the global domain to their bound domain while running their listeners. Therefore, we can think of domains as different error handling contexts that switch as the thread of execution enters different areas of your program.<\/p>\n<h2>How errors are routed<\/h2>\n<p>Now that we&#8217;ve seen how domains are set up and used, what actually happens when errors occur? That depends on the type of error, and as we&#8217;ve seen, there are 3 types: &#8216;error&#8217; events, exceptions and error arguments passed to callbacks.<\/p>\n<h3>&#8216;error&#8217; events<\/h3>\n<p>As we know, &#8216;error&#8217; events are a special event type in Node. They are emitted by event emitters whenever there is a problem, for example socket errors such as\u00a0<code>'EACCES'<\/code> triggered by <code>net.createServer.listen(1)<\/code>.<\/p>\n<p>When &#8216;error&#8217; is emitted on an event emitter:<\/p>\n<ol>\n<li>If &gt; 0 \u2018error\u2019 listeners, call it\/them with the error.<\/li>\n<li>Else, if there is a bound domain, emit &#8216;error&#8217; on it.<\/li>\n<li>Else, convert to exception and throw.<\/li>\n<\/ol>\n<p>You can see this logic in <a href=\"https:\/\/github.com\/joyent\/node\/blob\/cc56c62ed879ad4f93b1fdab3235c43e60f48b7e\/lib\/events.js#L60\" target=\"_blank\" rel=\"noopener noreferrer\">events.js<\/a>. The following example illustrates the propagation of steps 1-3:<\/p>\n<pre><code class=\"language-javascript\">\nvar EventEmitter = require('events').EventEmitter;\nvar domain       = require('domain');\n\nvar emitter = new EventEmitter();\n\n\/\/ Bind to domain\nvar d1 = domain.create();\nd1.on('error', function(err) {\n  console.log('Handled by domain:', err.stack);\n});\nd1.add(emitter);\n\n\/\/ Attach listener\nemitter.on('error', function(err) {\n  console.log('Handled by listener:', err.stack);\n});\n\nemitter.emit('error', new Error('this will be handled by listener'));\nemitter.removeAllListeners('error');\nemitter.emit('error', new Error('this will be handled by domain'));\nd1.remove(emitter);\nemitter.emit('error', new Error('woops, unhandled error. This is converted to an exception. Time to crash!'));\n<\/code><\/pre>\n<h3>Exceptions<\/h3>\n<p>Exceptions bubble up the call stack until they are caught\u00a0by a try\/catch block. If they are not caught, they climb out of your program, causing Node to do the following:<\/p>\n<ol>\n<li>Check if there is a domain active. If there is, it will <a href=\"https:\/\/github.com\/joyent\/node\/blob\/cc56c62ed879ad4f93b1fdab3235c43e60f48b7e\/src\/node.js#L249\" target=\"_blank\" rel=\"noopener noreferrer\">pass the exception<\/a> to the domain by emitting it as an <code class=\"language-javascript\">'error'<\/code> event on the domain object.<\/li>\n<li>Else, Node will check for\u00a0any listeners for the process&#8217; <code>'uncaughtException'<\/code> event (there <a href=\"http:\/\/nodejs.org\/api\/process.html#process_event_uncaughtexception\" target=\"_blank\" rel=\"noopener noreferrer\">shouldn&#8217;t be<\/a>) and call them with the error if they exist.<\/li>\n<li>Else, Node will pack up shop and terminate the process because an uncaught and unhandled exception essentially means the program is broken so it&#8217;s probably the best thing to do.<\/li>\n<\/ol>\n<h3>Callback arguments<\/h3>\n<p>In Node, the convention for callback arguments is <code>function(err, arg1, ...)<\/code>. If the asynchronous operation failed, err should\u00a0be passed as the first argument to the\u00a0callback and be an instance\u00a0of Error.<\/p>\n<h4>Binding domains directly to callbacks<\/h4>\n<p>When a callback runs, it is typically within a call stack with an event emitter or timer listener at the top. If the listener is called in the context of a bound domain, any uncaught errors coming from that callback will be handled by the domain.<\/p>\n<p>However, if you&#8217;d like to ensure the callback runs in the context of a different domain, you can bind it to the desired domain using <a href=\"http:\/\/nodejs.org\/api\/domain.html#domain_domain_bind_callback\" target=\"_blank\" rel=\"noopener noreferrer\"><code>domain.bind(fn)<\/code><\/a>.<\/p>\n<p>Furthermore, in a callback, you&#8217;d usually check for the err argument and handle it accordingly. Using\u00a0<a href=\"http:\/\/nodejs.org\/api\/domain.html#domain_domain_intercept_callback\" target=\"_blank\" rel=\"noopener noreferrer\"><code>domain.intercept(fn)<\/code><\/a>, you can instead delegate the error checking and handling step to a domain.<\/p>\n<h3>In conclusion<\/h3>\n<p>I was a little confused by domains at first. The domain stack and global active domain concept can get confusing. It all makes sense when you understand how event emitters and timers can be implicitly and explicitly bound to domains, and know how the different types of errors travel through your program. It really helps to read through the actual Node <a href=\"https:\/\/github.com\/joyent\/node\" target=\"_blank\" rel=\"noopener noreferrer\">source code<\/a> to follow the path of errors through domains and event emitters.<\/p>\n<p>Once that understanding is in place, domains are a very useful tool to help you handle crashes in your Node programs gracefully. They should be used with care due the dangerous nature of uncaught exceptions, but when harnessed properly they can help take the edge off nasty crashes and error conditions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a previous post about handling errors in Node.js programs, I took a look at how different flow control styles&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1452],"tags":[],"class_list":["post-618","post","type-post","status-publish","format-standard","hentry","category-engineering"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v18.6 (Yoast SEO v19.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Crash safety using domains in Node.js - GoSquared Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Crash safety using domains in Node.js\" \/>\n<meta property=\"og:description\" content=\"In a previous post about handling errors in Node.js programs, I took a look at how different flow control styles...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js\" \/>\n<meta property=\"og:site_name\" content=\"GoSquared Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/GoSquared\" \/>\n<meta property=\"article:published_time\" content=\"2014-06-03T12:22:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-28T12:09:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@TheDeveloper\" \/>\n<meta name=\"twitter:site\" content=\"@GoSquared\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Geoff Wagstaff\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\",\"name\":\"GoSquared\",\"url\":\"https:\/\/www.gosquared.com\/blog\/\",\"sameAs\":[\"https:\/\/instagram.com\/gosquaredteam\",\"https:\/\/www.linkedin.com\/company\/go-squared-ltd.\",\"https:\/\/www.facebook.com\/GoSquared\",\"https:\/\/twitter.com\/GoSquared\"],\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png\",\"contentUrl\":\"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png\",\"width\":1270,\"height\":250,\"caption\":\"GoSquared\"},\"image\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#website\",\"url\":\"https:\/\/www.gosquared.com\/blog\/\",\"name\":\"GoSquared Blog\",\"description\":\"Turn visitors into customers.\",\"publisher\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.gosquared.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#primaryimage\",\"url\":\"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png\",\"contentUrl\":\"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#webpage\",\"url\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js\",\"name\":\"Crash safety using domains in Node.js - GoSquared Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#primaryimage\"},\"datePublished\":\"2014-06-03T12:22:00+00:00\",\"dateModified\":\"2019-11-28T12:09:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.gosquared.com\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Crash safety using domains in Node.js\"}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#webpage\"},\"author\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448\"},\"headline\":\"Crash safety using domains in Node.js\",\"datePublished\":\"2014-06-03T12:22:00+00:00\",\"dateModified\":\"2019-11-28T12:09:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#webpage\"},\"wordCount\":1548,\"commentCount\":6,\"publisher\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#primaryimage\"},\"thumbnailUrl\":\"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png\",\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#respond\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448\",\"name\":\"Geoff Wagstaff\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g\",\"caption\":\"Geoff Wagstaff\"},\"sameAs\":[\"https:\/\/twitter.com\/TheDeveloper\"],\"url\":\"https:\/\/www.gosquared.com\/blog\/author\/echo\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Crash safety using domains in Node.js - GoSquared Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js","og_locale":"en_US","og_type":"article","og_title":"Crash safety using domains in Node.js","og_description":"In a previous post about handling errors in Node.js programs, I took a look at how different flow control styles...","og_url":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js","og_site_name":"GoSquared Blog","article_publisher":"https:\/\/www.facebook.com\/GoSquared","article_published_time":"2014-06-03T12:22:00+00:00","article_modified_time":"2019-11-28T12:09:37+00:00","og_image":[{"url":"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png"}],"twitter_card":"summary_large_image","twitter_creator":"@TheDeveloper","twitter_site":"@GoSquared","twitter_misc":{"Written by":"Geoff Wagstaff","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Organization","@id":"https:\/\/www.gosquared.com\/blog\/#organization","name":"GoSquared","url":"https:\/\/www.gosquared.com\/blog\/","sameAs":["https:\/\/instagram.com\/gosquaredteam","https:\/\/www.linkedin.com\/company\/go-squared-ltd.","https:\/\/www.facebook.com\/GoSquared","https:\/\/twitter.com\/GoSquared"],"logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png","contentUrl":"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png","width":1270,"height":250,"caption":"GoSquared"},"image":{"@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"WebSite","@id":"https:\/\/www.gosquared.com\/blog\/#website","url":"https:\/\/www.gosquared.com\/blog\/","name":"GoSquared Blog","description":"Turn visitors into customers.","publisher":{"@id":"https:\/\/www.gosquared.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.gosquared.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#primaryimage","url":"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png","contentUrl":"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png"},{"@type":"WebPage","@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#webpage","url":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js","name":"Crash safety using domains in Node.js - GoSquared Blog","isPartOf":{"@id":"https:\/\/www.gosquared.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#primaryimage"},"datePublished":"2014-06-03T12:22:00+00:00","dateModified":"2019-11-28T12:09:37+00:00","breadcrumb":{"@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.gosquared.com\/blog"},{"@type":"ListItem","position":2,"name":"Crash safety using domains in Node.js"}]},{"@type":"Article","@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#article","isPartOf":{"@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#webpage"},"author":{"@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448"},"headline":"Crash safety using domains in Node.js","datePublished":"2014-06-03T12:22:00+00:00","dateModified":"2019-11-28T12:09:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#webpage"},"wordCount":1548,"commentCount":6,"publisher":{"@id":"https:\/\/www.gosquared.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#primaryimage"},"thumbnailUrl":"https:\/\/static.gosquared.com\/images\/liquidicity\/14_06_02_errors_01@2x.png","articleSection":["Engineering"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.gosquared.com\/blog\/error-handling-using-domains-node-js#respond"]}]},{"@type":"Person","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448","name":"Geoff Wagstaff","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g","caption":"Geoff Wagstaff"},"sameAs":["https:\/\/twitter.com\/TheDeveloper"],"url":"https:\/\/www.gosquared.com\/blog\/author\/echo"}]}},"wps_subtitle":"A look at how domains can gracefully deal with unhandled errors and uncaught exceptions","_links":{"self":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts\/618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/comments?post=618"}],"version-history":[{"count":0,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts\/618\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/media?parent=618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/categories?post=618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/tags?post=618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}