JavaScript-エラー処理


エラー処理
JavaScriptコードを実行する場合、エラーが発生する場合があります.
エラーは二つの種類に分けられています.一つはプログラムで書かれたロジックが正しくないため、コードの実行が異常になりました.たとえば:
var s = null;
var len = s.length; // TypeError:null    length  
このようなエラーに対しては、プログラムを修復します.
一つは実行中、プログラムが予測できない異常な状況に遭遇してエラーを発生する可能性があります.例えば、ネットワーク接続が中断され、存在しないファイルを読み込み、操作権限がないなどです.
このようなエラーに対しては、私たちはそれを処理し、ユーザーにフィードバックする必要があります.
エラー処理はプログラム設計時に考慮しなければならない問題です.Cのようなシステムの下に近い言語では、エラーはエラーコードで返されます.
int fd = open("/path/to/file", O_RDONLY);
if (fd == -1) {
    printf("Error when open file!");
} else {
    // TODO
}
エラーコードでエラーを返すには、正しい戻り値とは何かを約束する必要があります.上記のopen()関数は、-1に戻ると約束しています.エラーを表しています.
明らかに、このようなエラーコードはエラーを表しています.
したがって、高級言語は通常より抽象的なエラー処理ロジックtry...catch...finallyを提供しています.JavaScriptも例外ではありません.
try…catch…finally
try...catch...finallyを使ってエラーを処理する時、私達が作成したコードは以下の通りです.
'use strict';
var 1,r 2,s=null
try{
    r 1=s.length;/ここでエラーが発生するべきです.
    r 2=100;/この文は実行されません.
}catch(e){
    consolie.log('エラー:'+e);
}finally{
    consolie.log('finally')
)
consolone.log('r 1='+r 1)//r 1はundefinedであるべきです
consolone.log('r 2='+r 2)/.r 2はundefinedであるべきです
//     
 Run
エラー:Type Error: Canot read property 'length 保存先 null
finally
r 1 = undefined
r 2 = undefined
運転後、出力メッセージは「エラーが発生しました.TypeError:Canot read property'length'of null」のようです.
try...catch...finallyを使った実行プロセスを分析します.
現代コードブロックがtry { ... }によって小包された時、この部分のコードの実行中にエラーが発生する可能性があることを表しています.エラーが発生したら、後続コードはもう実行しなくなり、catchブロックにジャンプします.catch (e) { ... }パッケージのコードはエラー処理コードであり、変数eはキャプチャされたエラーを表している.最後に、エラーがないにかかわらず、finallyは必ず実行される.
したがって、エラーが発生した場合、実行フローはこのようになります.
  • は、まずtry { ... }のコードを実行する.
  • でエラーが発生した文が実行された場合、後続の文は実行されなくなり、catch (e) { ... }コードが実行される.
  • は最後にfinally { ... }コードを実行します.
  • エラーが発生していない場合は、実行フローはこのようになります.
  • は、まずtry { ... }のコードを実行する.
  • エラーがないため、catch (e) { ... }コードは実行されません.
  • は最後にfinally { ... }コードを実行します.
  • 最後に、catchおよびfinallyは、すべて出現する必要がないことに注意してください.つまり、try文は全部で3つの形式があります.
    完全なtry...catch...finally:
    try {
        ...
    } catch (e) {
        ...
    } finally {
        ...
    }
    
    try...catchだけあって、finallyがありません.
    try {
        ...
    } catch (e) {
        ...
    }
    
    try...finallyだけあって、catchがありません.
    try {
        ...
    } finally {
        ...
    }
    
    エラーの種類
    JavaScriptには、標準的なErrorオブジェクトがあり、Errorから派生したTypeErrorReferenceErrorなどのエラーオブジェクトがあります.エラーを処理すると、catch(e)によって取り込まれた変数eを介してエラーオブジェクトにアクセスできます.
    try {
        ...
    } catch (e) {
        if (e instanceof TypeError) {
            alert('Type error!');
        } else if (e instanceof Error) {
            alert(e.message);
        } else {
            alert('Error: ' + e);
        }
    }
    
    使用変数eは慣用的な使用法であり、catch(ex)などの他の変数名で命名されてもよい.
    誤りを投げ出す
    プログラムは、実行フローを直接catchブロックに遷移させるために、エラーを自発的に投げ出してもよい.エラーを出してthrow文を使う.
    例えば、次のコードはユーザに数字を入力させ、プログラムが受信したのは実際に文字列であり、parseInt()で整数に変換される.ユーザーが合法的ではないと入力した時、私達はエラーを投げます.
    'use strict';
    
    var,n,s.
    try{
        s=prompt('は数字を入力してください')
        n=parseInt(s)
        if(isNaN(n){
            throw new Error('入力エラー')
        }
       //平方を計算:
        r=n*n;
        consolone.log(n+'+n+'='+r);
    }catch(e){
        consolie.log('エラー:'+e);
    )
    //     
    
     Run
    エラー:Errer: 入力エラー
    実際には、JavaScriptは、任意のオブジェクトに数字、文字列を含めることができます.
    最後に、catchでエラーを捕まえたら、必ずエラー処理文を作成します.
    var n = 0, s;
    try {
        n = s.length;
    } catch (e) {
        console.log(e);
    }
    console.log(n);
    
    エラーを印刷するだけでも、何もしないでください.
    var n = 0, s;
    try {
        n = s.length;
    } catch (e) {
    }
    console.log(n);
    
    catchはエラーがあっても何も実行しないので、プログラム実行中にエラーが発生したかどうかは分かりません.
    エラーを処理する時、簡単にalert()でエラーをユーザに表示しないでください.
    エラー伝搬
    コードが間違っていて、try...catchに捕捉されていない場合、プログラム実行フローはどこにジャンプしますか?
    function getLength(s) {
        return s.length;
    }
    
    function printLength() {
        console.log(getLength('abc')); // 3
        console.log(getLength(null)); // Error!
    }
    
    printLength();
    
    一つの関数の内部でエラーが発生した場合、それ自体は捕獲されていません.エラーは外層関数に呼び出されます.もし外層関数が捕獲されていないなら、このエラーはJavaScriptエンジンに捕捉されるまで、関数に沿ってチェーンを上に投げ続けます.コードは実行を終了します.
    したがって、私たちは各関数の内部でエラーを捕捉する必要はなく、適切なところで統一的に捕獲し、ネットワークを使って解決する必要があります.
    'use strict';
    
    function main(s){
        consolie.log('BEGIN main()')
        try{
            foo(s)
        } catch(e){
            consolie.log('エラー:'+e);
        }
        consolie.log('END main()')
    )
    function foo(s){
        consolie.log('BEGIN foo()')
        bar(s)
        consolie.log('END foo()')
    )
    function bar(s){
        consolie.log('BEGIN bar()')
        consolone.log('length='+s.length);
        consolie.log('END bar()')
    )
    メイン(null)
    //     ,       
    
     Run
    BEGIN main()
    BEGIN foo()
    BEGIN bar()
    エラー:Type Error: Canot read property 'length 保存先 null
    END main()alert()関数がパラメータbar()に入ったとき、コードはエラーとなり、エラーは呼び出し元null関数に投げられ、foo()関数はtry...catch文がないので、エラーは引き続き呼び出し元foo()関数に投げられ、main()関数はtry...catch文があり、エラーは最終的にmain()関数で処理されました.
    どのようなところで捕獲ミスが適切かは、状況によって異なります.
    非同期エラー処理
    JavaScriptコードを作成する時は、JavaScriptエンジンはイベント駆動の実行エンジンであり、コードは常にシングルスレッドで実行されますが、コールバック関数の実行は次の条件を満たすイベントが発生するまで待つ必要があります.
    例えば、main()関数は、コールバック関数に着信し、数ミリ秒を指定した後に実行することができる.
    function printTime() {
        console.log('It is time!');
    }
    
    setTimeout(printTime, 1000);
    console.log('done');
    
    上記のコードは先にsetTimeout()を印刷して、1秒後にdoneを印刷します.It is time!関数の内部にエラーが発生した場合、私たちはtryパッケージを使用しようとしています.printTime()は無効です.
    'use strict';
    
    function printTime(){
        throw new Error()
    )
    try{
        setTimeout(printTime、1000)
        consolone.log('done')
    }catch(e){
        consolone.log('error')
    )
    //     ,    alert
    donesetTimeout()関数を呼び出したときに、入ってきたsetTimeout()関数がすぐに実行されなかったからです.続いて、JavaScriptエンジンはprintTime文を実行し続けます.このときはエラーが発生しません.1秒後にconsole.log('done');関数を実行したときにエラーが発生しましたが、printTime関数の内部でエラーが発生した場合を除いて、外層コードは捕捉できません.
    したがって、非同期コードに関しては、呼び出し時に捕獲できない.なぜなら、キャプチャ時には、コールバック関数が実行されなかったからである.
    同様に、イベント処理関数のエラーは、結合イベントのコードにおいて捕獲できない.
    例えば、以下のフォームに対して:
    <form>
        <input id="x"> + <input id="y">
        <button id="calc" type="button">  button>
    form>
    
     +  計算する
    私たちは下のコードでbuttonにclickイベントをバインドしました.
    'use strict';
    
    var $btn = $('#calc');
    
    //         :
    $btn.off('click');
    
    try{
        $btn.click(function){
            var
                x=parseFlaoat(''噫x').val()
                y=parseFloat(''噫y').val()
                r;
            if(isNaN(x)𞓜isNaN(y){
                throw new Errer('入力に誤りがあります;)
            }
            r=x+y;
            alert('計算結果:'+r);
        });
    }catch(e){
        alert('入力が間違っています!')
    )
    (ノ out put)
    しかし、ユーザが入力ミスをした場合、処理関数はエラーをキャッチしませんでした.エラー処理コードを修正してください.