2013-05-27 85 views
0

使用以下代碼,我期望任務「asyncfail」導致某些錯誤輸出轉到控制檯並且退出代碼爲非零(就像任務「syncfail」一樣)。實際發生的是jake完成後沒有進一步輸出(下面的示例輸出),並且進程退出代碼表示成功。我不確定我是否在做傑克錯誤或承諾...任何想法?帶異步故障的傑克任務不會導致故障通知冒泡

var Q = require("q"); 

task("syncfail", function() { 
    fail("synchronous failure"); 
}); 

var http = require("http"); 

task("asyncfail", function() { 

    waitForSleep().then(waitForSleep).then(waitForSleep).then(waitForSleep).then(function() { 
     console.log("all done, time to fail"); 
     fail("This is the end"); 
    }); 

    console.log("finishing sync part"); 
}, { async:true}); 


function waitForSleep() { 
    var deferred = Q.defer(); 

    setTimeout(function() { 
    console.log("finished timeout"); 
    deferred.resolve(); 
    }); 

    return deferred.promise; 
} 

下面是任務syncfail(其中完成,我會期望)和asyncfail一些示例輸出(其中沒有完成,我會期望):

C:\src\letscodejavascript>node node_modules\jake\bin\cli.js -f .\jakerepro.js syncfail 
jake aborted. 
Error: synchronous failure 
    at api.fail (C:\src\letscodejavascript\node_modules\jake\lib\api.js:221:18) 
(See full trace by running task with --trace) 

C:\src\letscodejavascript [master]> $lastexitcode 
1 

C:\src\letscodejavascript [master]> .\jake.bat -f .\jakerepro.js asyncfail 

C:\src\letscodejavascript>node node_modules\jake\bin\cli.js -f .\jakerepro.js asyncfail 
finishing sync part 
finished timeout 
finished timeout 
finished timeout 
finished timeout 
all done, time to fail 

C:\src\letscodejavascript [master]> $lastexitcode 
0 

回答

1

原因失敗()沒有工作是失敗()通過拋出一個異常被捕獲到一個外層,但是這個異常被實現.then()所捕獲。爲了使fail()以這種方式按照預期工作,我需要在setTimeout中調用fail()來重新拋出.then()處理程序之外的錯誤。

var Q = require("q"); 

task("asyncfail", function() { 

    waitForSleepPromise() 
    .then(waitForSleepPromise) 
    .then(waitForSleepPromise) 
    .then(waitForSleepPromise) 
    .then(function() { 
     console.log("all done, time to fail"); 

     deferError(function() { 
      fail("This is the end", "fasdf"); 
     }); 
    }); 

    console.log("finishing sync part"); 
}, { async:true}); 


function waitForSleepPromise() { 

    var deferred = Q.defer(); 

    setTimeout(function() { 
    console.log("finished timeout"); 
    deferred.resolve(); 
    }, 10); 

    return deferred.promise; 
} 

function deferError(callback) { 
    try { 
    callback(); 
    } 
    catch (err){ 
    setTimeout(function() { 
     throw err; 
    }, 0); 
    } 
} 
+0

您也可以在您的諾言上調用.done()。 .done()重新拋出任何未處理的錯誤,從而允許jake的處理程序做正確的事情。 fwiw,bluebird.js勸阻使用.done()雖然我有點模糊,至於爲什麼。 o/\ o < - hi-fives坦率:) – busticated