JavaScriptの例外を処理する方法

小云云
小云云オリジナル
2017-11-28 10:05:241840ブラウズ

プログラマーはプログラムを作成するときに必ずエラーに遭遇します。この記事は JavaScript でのエラー処理の概念に基づいています。 JavaScript プログラムを作成する際の参考になれば幸いです。

デモデモ

使用するデモは GitHub からダウンロードできます。プログラムを実行すると、次のページが表示されます:

JavaScriptの例外を処理する方法

すべてのボタンがエラーをトリガーし、TypeError をスローします。このモジュールの定義は次のとおりです。

// scripts/error.jsfunction error() {var foo = {};return foo.bar();}


は error() で空のオブジェクト foo を定義しているため、 foo.bar() を呼び出すと、定義されていないためエラーが報告されます。単体テストを使用して検証してみましょう:

// tests/scripts/errorTest.jsit('throws a TypeError', function () {should.throws(error, TypeError);});


単体テストには Should.js で Mocha を使用しました。

コード ベースを複製し、依存関係パッケージをインストールした後、npm t を使用してテストを実行できます。もちろん、./node_modules/mocha/bin/mocha testing/scripts/errorTest.js のようなテスト ファイルを実行することもできます

信じてください、JavaScript のような動的言語では、誰でも簡単に遭遇してしまいます。このようなエラー。

不正な処理方法

ボタンに対応するイベント処理関数を次のように少し単純化して抽象化しました。

// scripts/badHandler.jsfunction badHandler(fn) {try {return fn();} catch (e) { }return null;}

badHandler は、badHandler 内で呼び出されるコールバック関数として fn を受け取ります。対応する単体テストを作成します:

// tests/scripts/badHandlerTest.jsit('returns a value without errors', function() {var fn = function()
{return 1;};var result = badHandler(fn);result.should.equal(1);});it('returns a null with errors', function() 
{var fn = function() {throw new Error('random error');};var result = badHandler(fn);should(result).equal(null);});

例外が発生した場合、badHandler は単純に null を返すことがわかります。コード全体を照合すると、問題が見つかります。

// scripts/badHandlerDom.js(function (handler, bomb) {var badButton = document.getElementById('bad');
if (badButton) {badButton.addEventListener('click', function () {handler(bomb);console.log('Imagine, getting promoted for hiding mistakes');});
}}(badHandler, error));

エラーが発生したときに try-catch して、null を返すだけだと、何が問題だったのかまったくわかりません。このフェイルサイレント戦略は UI の混乱やデータの混乱を引き起こす可能性があり、デバッグに数時間を費やしても try-catch のコードを無視する可能性があり、これが惨事の原因となります。コードが非常に複雑で、複数レベルの呼び出しがある場合、何が問題になったのかを見つけるのはほとんど不可能になります。したがって、サイレント障害戦略の使用はお勧めしません。より洗練されたアプローチが必要です。

悪くはないがやり方が悪い

// scripts/uglyHandler.jsfunction uglyHandler(fn) {try {return fn();} catch (e) {throw new Error('a new error');}}

エラーを処理する方法は、エラー e をキャッチしてから新しいエラーをスローすることです。これは確かに、静かに失敗するという以前の戦略よりも優れています。何か問題が発生した場合は、最初にスローされたエラー e が見つかるまで、レイヤーごとに戻ることができます。単にエラー (「新しいエラー」) をスローするだけでは情報が限られており、正確ではありません。エラー オブジェクトをカスタマイズして、より多くの情報を送信します。 。しかし、再度スローされたため、依然として未処理のエラーでした。

例外のインターセプト

1 つのアイデアは、すべての関数を try...catch で囲むことです:

// scripts/specifiedError.js// Create a custom errorvar SpecifiedError = function SpecifiedError(message)
 {this.name = 'SpecifiedError';this.message = message || '';this.stack = (new Error()).stack;};
 SpecifiedError.prototype = new Error();SpecifiedError.prototype.constructor = SpecifiedError;
 、//  scripts/uglyHandlerImproved.jsfunction uglyHandlerImproved(fn) {try {return fn();} catch (e)
  {throw new SpecifiedError(e.message);}}// tests/scripts/uglyHandlerImprovedTest.jsit('returns a specified error with errors',
   function () {var fn = function () {throw new TypeError('type error');};should.throws(function () {uglyHandlerImproved(fn);}, 
   SpecifiedError);});

ただし、そのようなコードは非常に肥大化し、読みにくく、非効率になります。まだ覚えていますか?この記事の冒頭で、JavaScript の例外は単なるイベントであると述べましたが、幸いなことに、グローバル例外イベント処理メソッド (onerror) があります。

function main(bomb) {try {bomb();} catch (e) {// Handle all the error things}}

スタック情報を取得

エラー情報をサーバーに送信できます:

// scripts/errorHandlerDom.jswindow.addEventListener('error', function (e) {var error = e.error;console.log(error);});

より詳細なエラー情報を取得し、データ処理の手間を省くために、fundebug の JavaScript 監視プラグインを使用して迅速に接続することもできます。 3 分以内にバグ監視サービスを開始します。

以下はサーバーが受信したエラー メッセージです:

スクリプトが別のドメイン名の下に配置されている場合、CORS を有効にしないと、スクリプト エラー以外の有用なエラー メッセージが表示されません。具体的な解決策を知りたい場合は、「スクリプトエラーの総合解析」を参照してください。

非同期エラー処理JavaScriptの例外を処理する方法

setTimeout の非同期実行のため、次のコード例外は try...catch によってキャッチされません:

// scripts/errorAjaxHandlerDom.jswindow.addEventListener('error', function (e)
{var stack = e.error.stack;var message = e.error.toString();if (stack) {message += '\n' + stack;}
var xhr = new XMLHttpRequest();xhr.open('POST', '/log', true);// Fire an Ajax request with error detailsxhr.send(message);});


try...catch ステートメントは現在の例外のみをキャプチャします。実行環境。ただし、上記の例外がスローされると、JavaScript インタプリタは try...catch 内に存在しないため、キャッチできません。すべての Ajax リクエストにも同じことが当てはまります。

少し改善して、非同期関数のコールバックに try...catch を記述することができます:

// scripts/asyncHandler.jsfunction asyncHandler(fn) {try {// This rips the potential bomb from the current contextsetTimeout(function () {fn();}, 1);} catch (e) { }}

ただし、そのようなルーチンではプロジェクトが try...catch でいっぱいになり、コードは非常に簡潔ではありません。また、JavaScript を実行する V8 エンジンでは、関数内での try...catch の使用は推奨されません。幸いなことに、これを行う必要はありません。グローバル エラー処理 onerror がこれらのエラーをキャッチします。

結論

私のアドバイスは、間違いを隠さず、勇気を出して吐き出すことです。コードのバグによってプログラムがクラッシュすることを誰も恥じる必要はありません。プログラムを中断して、ユーザーが最初からやり直せるようにすることができます。間違いは避けられず、それにどう対処するかが重要です。

上記の内容はJavaScriptエラーの対処方法です。役に立ったと思ったらすぐに保存してください。

関連する推奨事項:

書き込みプロセス中の vue.js の不規則なスペースとエラー報告の問題を解決する方法

PHP インストール拡張機能 mysqli の実装手順とエラー報告に対する完璧なソリューション

MySQLデータベースエラー: 接続が多すぎます 解決策

以上がJavaScriptの例外を処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。