Node.js Best Practice Exception Handling

后端 未结 10 1648
遥遥无期
遥遥无期 2020-11-22 04:19

I just started trying out node.js a few days ago. I\'ve realized that the Node is terminated whenever I have an unhandled exception in my program. This is different than the

10条回答
  •  眼角桃花
    2020-11-22 05:03

    nodejs domains is the most up to date way of handling errors in nodejs. Domains can capture both error/other events as well as traditionally thrown objects. Domains also provide functionality for handling callbacks with an error passed as the first argument via the intercept method.

    As with normal try/catch-style error handling, is is usually best to throw errors when they occur, and block out areas where you want to isolate errors from affecting the rest of the code. The way to "block out" these areas are to call domain.run with a function as a block of isolated code.

    In synchronous code, the above is enough - when an error happens you either let it be thrown through, or you catch it and handle there, reverting any data you need to revert.

    try {  
      //something
    } catch(e) {
      // handle data reversion
      // probably log too
    }
    

    When the error happens in an asynchronous callback, you either need to be able to fully handle the rollback of data (shared state, external data like databases, etc). OR you have to set something to indicate that an exception has happened - where ever you care about that flag, you have to wait for the callback to complete.

    var err = null;
    var d = require('domain').create();
    d.on('error', function(e) {
      err = e;
      // any additional error handling
    }
    d.run(function() { Fiber(function() {
      // do stuff
      var future = somethingAsynchronous();
      // more stuff
    
      future.wait(); // here we care about the error
      if(err != null) {
        // handle data reversion
        // probably log too
      }
    
    })});
    

    Some of that above code is ugly, but you can create patterns for yourself to make it prettier, eg:

    var specialDomain = specialDomain(function() {
      // do stuff
      var future = somethingAsynchronous();
      // more stuff
    
      future.wait(); // here we care about the error
      if(specialDomain.error()) {
        // handle data reversion
        // probably log too
      } 
    }, function() { // "catch"
      // any additional error handling
    });
    

    UPDATE (2013-09):

    Above, I use a future that implies fibers semantics, which allow you to wait on futures in-line. This actually allows you to use traditional try-catch blocks for everything - which I find to be the best way to go. However, you can't always do this (ie in the browser)...

    There are also futures that don't require fibers semantics (which then work with normal, browsery JavaScript). These can be called futures, promises, or deferreds (I'll just refer to futures from here on). Plain-old-JavaScript futures libraries allow errors to be propagated between futures. Only some of these libraries allow any thrown future to be correctly handled, so beware.

    An example:

    returnsAFuture().then(function() {
      console.log('1')
      return doSomething() // also returns a future
    
    }).then(function() {
      console.log('2')
      throw Error("oops an error was thrown")
    
    }).then(function() {
      console.log('3')
    
    }).catch(function(exception) {
      console.log('handler')
      // handle the exception
    }).done()
    

    This mimics a normal try-catch, even though the pieces are asynchronous. It would print:

    1
    2
    handler
    

    Note that it doesn't print '3' because an exception was thrown that interrupts that flow.

    Take a look at bluebird promises:

    • https://github.com/petkaantonov/bluebird

    Note that I haven't found many other libraries other than these that properly handle thrown exceptions. jQuery's deferred, for example, don't - the "fail" handler would never get the exception thrown an a 'then' handler, which in my opinion is a deal breaker.

提交回复
热议问题