If we know where the error is occurring is synchronous code, and for whatever reason can't use domains (perhaps old version of node), we can use the try catch statement:
(如果我们知道错误发生在哪里是同步代码,并且由于某种原因不能使用域(也许是旧版本的节点),则可以使用try catch语句:)
// catch the uncaught errors in this synchronous code block // try catch statements only work on synchronous code try { // the synchronous code that we want to catch thrown errors on var err = new Error('example') throw err } catch (err) { // handle the error safely console.log(err) }
However, be careful not to use try...catch
in asynchronous code, as an asynchronously thrown error will not be caught:
(但是,请注意不要在异步代码中使用try...catch
,因为将不会捕获异步引发的错误:)
try { setTimeout(function(){ var err = new Error('example') throw err }, 1000) } catch (err) { // Example error won't be caught here... crashing our app // hence the need for domains }
If you do want to work with try..catch
in conjunction with asynchronous code, when running Node 7.4 or higher you can use async/await
natively to write your asynchronous functions.
(如果您确实想将try..catch
与异步代码一起使用,则在运行Node 7.4或更高版本时,可以本地使用async/await
编写异步函数。)
Another thing to be careful about with try...catch
is the risk of wrapping your completion callback inside the try
statement like so:
(使用try...catch
要注意的另一件事是将完成回调包装在try
语句中的风险,如下所示:)
var divide = function(x,y,next) { // if error condition? if ( y === 0 ) { // "throw" the error safely by calling the completion callback // with the first argument being the error next(new Error("Can't divide by zero")) } else { // no error occured, continue on next(null, x/y) } } var continueElsewhere = function(err, result){ throw new Error('elsewhere has failed') } try { divide(4, 2, continueElsewhere) // ^ the execution of divide, and the execution of // continueElsewhere will be inside the try statement } catch (err) { console.log(err.stack) // ^ will output the "unexpected" result of: elsewhere has failed }
This gotcha is very easy to do as your code becomes more complex.
(随着代码变得更加复杂,此陷阱非常容易实现。)
As such, it is best to either use domains or to return errors to avoid (1) uncaught exceptions in asynchronous code (2) the try catch catching execution that you don't want it to. (因此,最好使用域或返回错误,以避免(1)异步代码中未捕获的异常(2)尝试捕获不需要的执行。)
In languages that allow for proper threading instead of JavaScript's asynchronous event-machine style, this is less of an issue. (在允许适当的线程而不是JavaScript的异步事件机器风格的语言中,这不是问题。)
Finally, in the case where an uncaught error happens in a place that wasn't wrapped in a domain or a try catch statement, we can make our application not crash by using the uncaughtException
listener (however doing so can put the application in an unknown state ):
(最后,在未包裹域或try catch语句的地方发生未捕获的错误的情况下,我们可以使用uncaughtException
侦听器使应用程序不崩溃(但是这样做会使应用程序处于未知状态)状态 ):)
// catch the uncaught errors that weren't wrapped in a domain or try catch statement // do not use this in modules, but only in applications, as otherwise we could have multiple of these bound process.on('uncaughtException', function(err) { // handle the error safely console.log(err) }) // the asynchronous or synchronous code that emits the otherwise uncaught error var err = new Error('example') throw err