web-dev-qa-db-ja.com

awaitを使用せずにasyncからエラーをキャッチできますか?

待機していない非同期呼び出しからのエラーをキャッチしたり、元のカプセル化try/catchに送信したり、キャッチされなかった例外を発生させたりできますか?

ここに私が意味するものの例があります:

async function fn1() {
    console.log('executing fn1');
}

async function fn2() {
    console.log('executing fn2');
    throw new Error('from fn2');
}

async function test() {
    try {
        await fn1();
        fn2();
    }
    catch(e) {
        console.log('caught error inside test:', e);
    }
}

test();

このシナリオでは、fn2からスローされたエラーは黙って飲み込まれ、元のtry/catchに捕捉されません。 fn2はおそらく将来のある時点で終了するためにイベントループに追いやられており、testはいつ終了するかを気にしません(これは意図的なものです) )。

try/catchfn2の内部に置き、エラーを出力するようなことをする以外に、このような構造によってエラーが誤って飲み込まれないようにする方法はありますか?キャッチする方法がわからなくても、キャッチされていないエラーで解決することさえあると思います-スローされたエラーは、私が書いているものの典型的なプログラムの流れであるとは思いませんが、エラーを飲み込むとデバッグが比較的面倒になります。

サイドノート、私はバベルを使ってbabel-runtime変換を使用してコードをトランスパイルし、ノードでそれを実行しています。

27
dvlsg

未処理の拒否されたネイティブプロミスの処理(およびasync/awaitはネイティブプロミスの使用)は、V8で現在サポートされている機能です。これは、最新のChromeで使用され、拒否されたプロミスが処理されない場合にデバッグ情報を出力します。 the Babel REPL

_async function executor() {
  console.log("execute");
}

async function doStuff() {
  console.log("do stuff");
  throw new Error("omg");
}

function handleException() {
  console.error("Exception handled");
}

(async function() {
  try {
      await executor();
      doStuff();
  } catch(e) {
      handleException();
  }
})()
_

doStuff()からの例外が失われたとしても(呼び出し時にawaitを使用していないため)、Chromeは拒否された約束はコンソールに処理されませんでした:

Screenshot

これはNode.js 4.0以降でも使用できますが、 特別なunhandledRejection event をリッスンする必要があります。

_process.on('unhandledRejection', function(reason, p) {
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging, throwing an error, or other logic here
});
_
27
Michelle Tilley