JavaScriptで可能な{}キャッチなしで{}を試しますか?


114

何かを返すか、エラーをスローする関数がいくつかあります。メイン関数でこれらをそれぞれ呼び出し、各関数から返された値を返すか、最初の関数がエラーをスローした場合は2番目の関数に進みます。

だから基本的に私が現在持っているのは:

function testAll() {
    try { return func1(); } catch(e) {}
    try { return func2(); } catch(e) {} // If func1 throws error, try func2
    try { return func3(); } catch(e) {} // If func2 throws error, try func3
}

しかし、実際にはtryそれを返したいだけです(つまり、エラーがスローされない場合)。catchブロックはいらない。ただし、try {}(未使用)catch {}ブロックがないため、などのコードは失敗します。

私は入れjsFiddleに例を

それで、catch同じ効果を達成しながらこれらのブロックを削除する方法はありますか?

回答:


4

いいえ。それらを保持する必要があります。

エラーは黙って無視されるべきではないので、これは実際に理にかなっています。


16
その場合、これらの関数はエラーをスローするのではなく、たとえばnull、戻り値を返す必要がありますreturn func1() || func2() || func3();
ThiefMaster

52
この答えは実際には正しくありません。stackoverflow.com/ a / 5764505/68210try {}; finally {}
Daniel X Mooreに

4
@DanielXMooreは、なしcatch (e) {}、でスローされた例外をfunc1()妨げるfunc2()試みられてから。
binki 14

65
空の漁獲量を持つことは完全に理にかなっている場合があるので、私はあなたの主張に同意しません。
Petr Peller、

8
この答えは事実として正しくなく、誤解を招くものです。「それは実際に理にかなっている」とあなたは言いますが、あなたは間違っています。これは、ひどい答えが不可解に受け入れられた素晴らしい例です。async関数のように、catchブロックがないことが理にかなっている場合が多くあります。JavaScript言語によって空のcatchブロックを作成するように強いられても、明らかに無意味です。
YungGun

236

試しなしのcatch句は次の上位にそのエラーを送りキャッチその試みの中に定義されたキャッチがない場合、またはウィンドウ。

catchがない場合、try式にはfinally節が必要です。

try {
    // whatever;
} finally {
    // always runs
}

したがって、最良の方法は次のようなものを書くことtry { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}でしょうか?
user2284570 14

1
上記のコメントは、関数1が成功した場合に関数2を実行したくないので、OPに正確に回答していません。
Andrew Steitz


それが私が必要としたものですありがとうございます:-)それが試さなくても機能するならそれは本当に素晴らしいでしょう{}つまり:async()=> {describeWorkInProgress()await pipelineStep1()await pipelineStep2()...最後に{stopIndicator( )}}関数全体が意図されていることは明らかです;-)これらのtryブロックはとても醜いです...
Lenny

35

ES2019以降、エラー変数なしで空のcatchブロックを使用することができます。これはオプションのキャッチバインディングと呼ばれ、2018年6月にリリースされたV8 v6.6で実装されました。この機能は、Node 10Chrome 66Firefox 58Opera 53Safari 11.1から利用できます。

構文を以下に示します。

try {
  throw new Error("This won't show anything");
} catch { };

それでもcatchブロックは必要ですが、空にすることができ、変数を渡す必要はありません。catchブロックがまったく必要ない場合は、try/ を使用できますがfinally、空のcatchのようにエラーを飲み込まないことに注意してください。

try {
  throw new Error("This WILL get logged");
} finally {
  console.log("This syntax does not swallow errors");
}


2
この回答が最新です。実行順序に関しては、1 try.ブロックを試みます。2.エラーをキャッチします。3. finallyブロックを実行します。4.エラーをスローします。これは正しいです?
Helsont

@helsontに感謝します。2番目のコードサンプルの実行順序については、エラーがキャッチされて再スローされたのか、単に(おそらく)単にスローされて最初の場所にキャッチされなかったのか(がないためcatch)がわかりません。コード全体を別のtry/で囲むcatchと、This WILL get loggedエラーをキャッチできます。
Dan Dascalescu

今とてもきれいに見えます。共有してくれてありがとう!
LeOn-Han Li

10

いいえcatch(またはfinally)はtry友達であり、常にtry / catchの一部としてそこにいます。

ただし、例のように空にすることは完全に有効です。

コード例のコメント(func1がエラーをスローする場合はfunc2を試してください)では、実際に実行したいのcatchは、前のブロック内の次の関数を呼び出すことです。


1
あなたは正しいです。ただし、次のようなコードtry {...}; try {...}が可能である場合は、コードの意味がより明確になる場合があります(最初に試して、それ以外の場合は2番目に試してください)。
pimvdb 2011

編集について:JSFiddleの例では、2番目の関数が何かを返すので、その場合、3番目の関数は本当に評価されますか?return発言がその後に続くことを止めると思いました。
pimvdb 2011

@pimvdb申し訳ありませんが、フィドルを確認していません。return関数が時期尚早に戻る原因となります。回答を更新します。
アレックス2011

1
この答えは実際には正しくありません。stackoverflow.com/ a / 5764505/68210try {}; finally {}
Daniel X Mooreに

1
@DanielXMoore確かにそうですが、finally{}基本的にはと同じ精神catch{}です。答えを更新します。
アレックス、2014

6

私のテストでは、catchなしでtry-finallyをお勧めしません。tryブロックとfinallyブロックの両方がエラーをスローした場合、finally句でスローされたエラーがバブルアップし、tryブロックのエラーは無視されます。

try {
  console.log('about to error, guys!');
  throw new Error('eat me!');
} finally {
  console.log ('finally, who cares');
  throw new Error('finally error');
}

結果:

>     about to error, guys!
>     finally, who cares
>     .../error.js:9
>         throw new Error('finally error');
>         ^
>     
>     Error: finally error

1

それらは私が知っているすべての言語(JavaScript、Java、C#、C ++)で一緒に使用されます。しないでください。


1
私がここで他の答えと同じことを言っているとき、私が5年後に反対投票されたのは奇妙です。反対票が投じられたのは鉱山だけです。モデレーター、注意してください。
duffymo 2016

Tclには非常に便利な単一語構成がありますcatch {my code}
MKaama 2016年


どうして?それがtry / finallyでない限り、役に立たないと感じます。
duffymo

1

別の角度から提示された問題を見ることにしました。

別のコメンターによってリストされた未処理のエラーオブジェクトに部分的に対処しながら、要求されたコードパターンを厳密に許可する方法を決定することができました。

コードはhttp://jsfiddle.net/Abyssoft/RC7Nw/4/で見ることができます

try:catchは、優雅なフォールスルーを可能にするforループ内に配置されます。必要なすべての機能を反復することができます。明示的なエラー処理が必要な場合は、追加の関数配列が使用されます。エラーとエラーハンドラー要素を持つ関数配列が関数でない場合でも、エラーはコンソールにダンプされます。

ここでのスタックオーバーフローの要件ごとに、インラインコードがあります[JSLintに準拠するように編集(確認のために先頭のスペースを削除)、読みやすさを向上]

function func1() {"use strict"; throw "I don't return anything"; }
function func2() {"use strict"; return 123; }
function func3() {"use strict"; throw "I don't return anything"; }

// ctr = Code to Run <array>, values = values <array>, 
// eh = error code can be blank.
// ctr and params should match 1 <-> 1
// Data validation not done here simple POC
function testAll(ctr, values, eh) {
    "use strict";
    var cb; // cb = code block counter
    for (cb in ctr) {
        if (ctr.hasOwnProperty(cb)) {
            try {
                return ctr[cb](values[cb]);
            } catch (e) {
                if (typeof eh[cb] === "function") {
                    eh[cb](e);
                } else {
                    //error intentionally/accidentially ignored
                    console.log(e);
                }
            }
        }
    }
    return false;
}

window.alert(testAll([func1, func2, func3], [], []));


1

エラーが発生した場合に関数2と関数3のみを起動する場合は、なぜそれらをcatchブロックに配置しないのですか?

function testAll() {
  try {
    return func1();
  } catch(e) {
    try {
      return func2();
    } catch(e) {
      try {
        return func3();
      } catch(e) {
        // LOG EVERYTHING FAILED
      }
    }
  }
}

0

次のようなヘルパー関数を使用する必要があると思います。

function tryIt(fn, ...args) {
    try {
        return fn(...args);
    } catch {}
}

そしてそれを次のように使用します:

tryIt(function1, /* args if any */);
tryIt(function2, /* args if any */);


-2

ES2019以降は、次のようにtry {}せずに簡単に使用できますcatch {}

try {
  parseResult = JSON.parse(potentiallyMalformedJSON);
} catch (unused) {}

詳細については、Michael Ficcara の提案を参照してください。


1
いいえ、catchまだ必要です。必要ないのはバインディングだけです...
chipit24
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.