Javascriptの組み込みError
は有用な情報を提供しますが、しばしば明快さに欠けていると感じることがあります。 フリーサイズは、すべての言語のための素晴らしいですが、我々は我々自身のアプリでより良い行うことができます。 そこでカスタムエラーが発生します。
ノードを使用しているときにカスタムエラーが表示されることがあります。js”を発表した。 ノードの組み込みエラータイプは次のようになりますAssertionError
, RangeError
, ReferenceError
, SyntaxError
, そしてSystemError
はすべてネイティブのError
クラスの拡張です。
Error
をベースとして使用すると、Javascriptの実装のすべての力に加えて、追加の利点が得られます。 ここにちょうど少数はある:
- カスタムエラーメッセージ形式。
- エラーオブジェクトの追加プロパティ。
- は、デバッグと条件付きエラー処理を容易にするためにerrorsという名前を付けました。
- ライブラリの消費者が参照する一貫性のあるエラー。
エラークラスの拡張
始めるには、一般的な例を使用してみましょう。 Error
クラスを拡張し、super
を使用して関数を継承します。
class CustomError extends Error { constructor(...params) { super(...params) // We're spreading `params` as a way to bring all of `Error`'s functionality in. }}
今、あなたはthrow
エラーが発生したとき、あなたはthrow new CustomError("Something went wrong...")
でそうすることができます。 また、タイプに対してエラーをチェックする機能も提供します:
try { throw new CustomError("Something went wrong")} catch (error) { if (error instance of CustomError) { // do something specifically for that type of error }}
これだけでは、呼び出してチェックする新しいエラータイプを与える以外にはあまりありません。 何ができるかをよりよく理解するために、Error
の標準的なものを見てみましょう。
- Error.name
- エラー。メッセージ
- エラー。プロトタイプ。toString()
- エラー。プロトタイプ。コンストラクタ()
で動作するように多くはありませんか? コンストラクタとtoString
メソッドを除いて、エラーの名前とエラーを説明するメッセージは、私たちが使用する可能性のある唯一の部分です。 上記の例では、message
は、エラーをインスタンス化するときに引数として”something wrong”を渡すことによって設定されます。
幸いなことに、ブラウザやノードのようなほとんどのjavascriptプラットフォーム。jsは、リストされているものの上に独自のメソッドとプロパティを追加しました。 ここでは、ChromeとNodeを動かすJavascriptエンジンであるV8のエラー実装のいくつかの側面に焦点を当てます。js”を発表した。
関心のある2つの領域はstack
とcaptureStackTrace
です。 その名前が示すように、スタックトレースを表面化することができます。 例を見て、それがどのように見えるかを見てみましょう。
class CustomError extends Error { constructor(...args) { super(...args) if (Error.captureStackTrace) { Error.captureStackTrace(this, CustomError) } this.name = "Our Custom Error" }}try { throw new CustomError("Something went wrong")} catch (err) { console.error(err.stack)}
この例では、プラットフォームがサポートしている場合はError.captureStackTrace
を呼び出して、カスタムエラーに完全なトレースが追加されるようにしています。 次に、try
ブロック内からthrow
エラーが発生し、catch
ブロックに制御が渡されます。上記のコードを実行すると、stack
の最初の行がエラーのname
およびmessage
であることがわかります。
Our Custom Error: Something went wrong
このエラーはあまり「深い」ものではないので、スタックは主にノードです。jsの内部。 各行はスタックの1つの「フレーム」です。 これらには、コードベース内のエラーの場所に関する詳細が含まれています。
カスタムエラーを作成して呼び出す方法がわかったので、それを便利にしましょう。
エラー内容のカスタマイズ
私たちが作業してきたカスタムエラーは問題ありませんが、より便利にするために変更しましょう。 クラスはCircuitError
になります。 私たちは、回路ブレーカから来るカスタムエラーを提供するためにそれを使用します。 あなたがパターンに精通していない場合、それは大丈夫です。 回路ブレーカの実装の詳細は重要ではありません。 重要なのは、エラーにいくつかの情報を渡すことができ、その情報をユーザーに提示することです。
ブレーカは一定時間何も通過できない”オープン”状態を持っています。 状態がOPEN
のときにそれを受け取る関数に役立つかもしれないいくつかの詳細を含むようにCircuitError
を設定しましょう。
class CircuitError extends Error { // 1 constructor(state, nextAttempt, ...params) { super(...params) if (Error.captureStackTrace) { Error.captureStackTrace(this, CircuitError) } this.name = "CircuitError" this.state = state // 2 this.message = `The Circuit is ${state}.` // 3 if (nextAttempt) { this.timestamp = Date.now() this.nextAttempt = nextAttempt this.message += ` Next attempt can be made in ${this.nextAttempt - this.timestamp}ms.` } }}
更新されたエラーは、すべてコンストラクタ内でいくつかの新しいことを行います。 渡された引数は(1)変更され、遮断器のstate
と、遮断器が要求の再試行を開始する時期を示すnextAttempt
タイムスタンプが含まれます。
その後、いくつかの新しいプロパティを設定し、表示された値に応じてメッセージを更新します。 このエラーの新しいバージョンをスローすることでテストできます。
try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { console.error(err)}
ここで、エラーをスローすると、最初の引数として状態を、2番目の引数としてタイムスタンプを受け取ります。 このデモでは、将来的に8000ミリ秒の時間を経過しています。 スタックだけではなく、エラー自体もログに記録していることに注意してください。
コードを実行すると、次のような結果になります:
CircuitError : The Circuit is OPEN. Next attempt can be made in 6000ms. at Object.<anonymous> (/example.js:21:9) at Module._compile (internal/modules/cjs/loader.js:1063:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1103:10) at Module.load (internal/modules/cjs/loader.js:914:32) at Function.Module._load (internal/modules/cjs/loader.js:822:14) at Function.Module.runMain (internal/modules/cjs/loader.js:1143:12) at internal/main/run_main_module.js:16:11 { name: 'Circuit Error', state: 'OPEN', message: 'The Circuit is OPEN. Next attempt can be made in 6000ms.', timestamp: 1580242308919, nextAttempt: 1580242314919}
結果は、エラー名の後に最初の行のメッセージが続きます。 次に、残りのスタックがあり、その後にCircuitError
で設定したすべてのプロパティが続きます。 このエラーの消費者は、そのデータを使用してエラーに反応することができます。 例えば:
try { throw new CircuitError("OPEN", Date.now() + 8000)} catch (err) { customLogger(err) if (err.state === "OPEN") { handleOpenState(err.nextAttempt) }}
一般的なエラーの代わりに、アプリケーションのニーズにより適したものがあります。
障害に反応する
カスタムエラーは、障害に反応するのに最適な方法です。 すべてのエラーが予期しないものであると仮定するのが一般的ですが、有用なエラーを提供することで、その存在を処理しやすくすることができます。 カスタムエラーを利用することで、アプリケーションのユーザーに貴重なデータを提供するだけでなく、instance of
条件を介してエラータイプに応答する機能も提供します。
Bearerでは、カスタムエラーを使用してコード内の応答を標準化し、クライアントに必要な情報だけを提供し、エラーを実用的にすることができます。
アプリケーションでカスタムエラーをどのように使用していますか? 私たち@BearerSHと接続し、私たちに知らせてください。