2016-11-17 109 views
3

我正在使用异步瀑布。当我的一个函数调用callback(err)时,我的自定义异步回调被调用。在那里我抛出了一个错误,希望它能够在异步的try块中被捕获,但是这没有发生。节点异步和异常处理

try { 
    async.waterfall([function1, function2], myAsyncCallback); 
} 
catch(err) { 
    console.log("THIS CODE IS NEVER EXECUTED."); 
} 

var function1 = function() { 
... 
    //some error occurs: 
    callback(new Error(errMsg), errMsg); 
... 
} 

var function2 = function() { 
... 
} 

function myAsyncCallback(err, result) { 
    console.log("This code gets executed."); 
    if (err) { 
      console.log("This code gets executed too."); 
      throw new Error("I want this error caught at the top around the catch around async.waterfall()"); 
     } 
} 
+0

这是代码格式化的问题:现在你'声明* myAsyncCallback'里面你'function1'的*,所以这是不是真的懂事代码。你可以减少这个[mcve],人们可以复制粘贴到文件并运行在节点上看到你看到的相同的东西,而不是发布代码,保证不会显示你的问题,因为它不能运行? –

+0

@Mike,他们实际上并不在彼此之内。更新了样本,希望能够说清楚。你应该能够删除“...”来测试它。 – user994165

+0

我添加了一个答案,但可能需要更深入了解所调用的函数。我发布了我的工作代码,这看起来很像你的例子! – clay

回答

1

https://runkit.com/imjosh/async-try-catch/2.0.0

var async = require('async'); 

try { 
    async.waterfall([function1, function2], myAsyncCallback); 
} 
catch(err) { 
    errorHandler(err); 
} 

function function1(callback) { 
    console.log('in fn1') 
    callback(null,'fn1'); 
} 

function function2(fn1, callback) { 
    console.log('in fn2') 
    callback(null, fn1 + 'fn2'); 
} 

function myAsyncCallback(err, result) { 
    if (err) { 
     console.error('There was an error: ' + err); 
     return; 
    } 
    //an error occurs. this gets caught by the outer try block 
    //var foo = outer; //oops, outer is not defined. This throws an error 

    //same scenario but inside an async function 
    //can't/won't be caught by the outer try block 
    setTimeout(function(){ 
     try{ //need try here 
      var foo = inner; //oops, inner is not defined. This throws an error 
     } 
     catch(err) { 
      errorHandler(err); 
     } 
    }, 1000); 

    console.log('Result was: ' + result); 
} 

function errorHandler(err){ 
    //Make error handler a function that can be called from either catch 
    console.log('caught error: ' + err); 
} 
+0

错误发生在异步模块回调中,我称之为myAsyncCallback。函数1中的错误会被第一个try/catch块捕获,但这不是我想要做的。 – user994165

+0

我编辑了答案。所有的错误处理都在一个地方。处理myAsyncCallback中的异常。看到您的实际代码时很难看到您想要做什么。 – imjosh

0

适合我。你看到有什么不同吗?如果有更多的话,我会更新我的答案。

这是我的输出:

[Clays-MacBook-Pro ~/Documents/workspace/scratch]:node index.js 
inside function1 
This code gets executed. 
This code gets executed too. 
THIS CODE IS NEVER EXECUTED. 
[Clays-MacBook-Pro ~/Documents/workspace/scratch]:node -v 
v6.9.1 
[Clays-MacBook-Pro ~/Documents/workspace/scratch]: 

此代码:

var async = require('async') 
try { 
    async.waterfall([function1, function2], myAsyncCallback); 
} 
catch(err) { 
    console.log("THIS CODE IS NEVER EXECUTED."); 
} 

function function1(callback) { 
    console.log("inside function1"); 
    var errMsg = "Uh oh"; 
    callback(new Error(errMsg), errMsg); 
} 

function function2(stuff2, callback) { 
    console.log('inside function2'); 
    var errMsg = "Uh oh"; 
    callback(new Error(errMsg), errMsg); 
} 

function myAsyncCallback(err, result) { 
    console.log("This code gets executed."); 
    if (err) { 
      console.log("This code gets executed too."); 
      throw new Error("I want this error caught at the top around the catch around async.waterfall()"); 
     } 
    console.log(result); 
} 
+0

你的'function1'和'function2'正在同步调用它们的回调函数,这没有任何意义。 'myAsyncCallback'应该是一个*异步*回调,否则'async.waterfall'首先不会被使用。 – Bergi

+0

Bergi,我相信我们应该在每个函数中调用回调函数(例如https://www.hacksparrow.com/node-js-async-programming.html)。让我们将正常的异步处理变为同步处理。也许我错过了一些东西。 – user994165

+0

@Clay,你的样品为我工作。为了测试我的代码中的错误处理,我在回调中添加了throw语句,但我没有创建错误并将其发送到回调:callback(err)。在我的代码中,在上面的示例中,有一个if/else代替了“...”,导致回调调用不被执行。 – user994165

1

希望它会在周围异步try块被抓住,但没有发生

这是不可能的。错误将被创建并异步抛出,即在async.waterfall已返回并且try块被留下之后很久。如果您想处理异步错误,请在myAsyncCallback中执行(就像您已经这样做)。在异步回调中从不使用throw

+0

这不是准确的。调用'async.waterfall'时创建的作用域将一直保留,直到连锁死亡。抛出的错误会通过呼叫链“回升”。我同意抛出一个异步回调是有问题的(因为跟踪错误非常痛苦),但这不是不可能的。你能编辑这个答案吗? – clay

+0

@clay你在说什么范围? OPs代码中没有关闭,因此范围在离开时被破坏。或者,“直到链条死亡”是什么意思?请注意,引发OP代码的'myAsyncCallback'不会被'async.waterfall'调用 - 它是* asynchronous *。 – Bergi

+0

我想我是指回调链。但是你是正确的,如果回调是异步调用的,则会有不同的行为。我猜想,我有一些学习要做!感谢您的回答。 – clay