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
4

1 に答える 1

1

fail() が機能しなかった理由は、fail() が例外をスローして外側のレイヤーでキャッチすることによって機能するためですが、その例外は代わりに .then() の実装によってキャッチされていました。この方法で promise を使用しているときに fail() を期待どおりに機能させるには、fail() の呼び出しを setTimeout でラップして、.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);
  }
}
于 2013-05-29T23:28:50.683 に答える