Welcome to Our Website

Custom errors,extending Error

何かを開発するとき、タスクで間違っている可能性のある特定のものを反映するために、独自のエラークラスが必要になることが ネットワーク操作のエラーについては、HttpError、データベース操作の場合はDbError、検索操作の場合はNotFoundErrorなどが必要になる場合があります。

私たちのエラーは、messagename、できればstackのような基本的なエラープロパティをサポートする必要があります。 もしその他の特性、例えば, HttpErrorオブジェクトは、statusCode404または403または500のような値を持つstatusCodeプロパティを持つことができます。

JavaScriptではthrowを任意の引数で使用できるため、技術的にはカスタムエラークラスはErrorから継承する必要はありません。 しかし、継承すると、obj instanceof Errorを使用してエラーオブジェクトを識別できるようになります。 だから、それから継承する方が良いです。

アプリケーションが成長するにつれて、私たち自身のエラーは自然に階層を形成します。, たとえば、HttpTimeoutErrorHttpErrorから継承することができます。

拡張エラー

例として、JSONをユーザーデータで読み取る関数readUser(json)を考えてみましょう。

有効なjsonがどのように見えるかの例を次に示します。

let json = `{ "name": "John", "age": 30 }`;

内部的には、JSON.parseを使用します。 不正な形式のjsonを受け取った場合、SyntaxErrorをスローします。, しかし、たとえjson構文的に正しい場合でも、それはそれが有効なユーザーであることを意味するものではありませんよね? 必要なデータを見逃すことがあります。 たとえば、ユーザーにとって不可欠なnameおよびageプロパティがない場合があります。

私たちの関数readUser(json)JSONを読み取るだけでなく、データをチェック(”検証”)します。 必須フィールドがない場合、または形式が間違っている場合、それはエラーです。 そして、データは構文的に正しいので、それはSyntaxErrorではなく、別の種類のエラーです。, これをValidationErrorと呼び、そのためのクラスを作成します。 その種のエラーは、問題のあるフィールドに関する情報も運ぶ必要があります。

私たちのValidationErrorクラスは、組み込みのErrorクラスから継承する必要があります。

そのクラスは組み込まれていますが、拡張しているものを理解できるように、おおよそのコードがあります。

次に、ValidationErrorを継承して、実際に試してみましょう。

注意してください:(1)行では、親コンストラクタを呼び出します。, JavaScriptでは、子コンストラクタでsuperを呼び出す必要があるため、これは必須です。 親コンストラクターは、messageプロパティを設定します。

親コンストラクタは、nameプロパティを"Error"に設定するため、(2)行で正しい値にリセットします。,

readUser(json)で使用してみましょう:

上記のコードのtry..catchブロックは、ValidationErrorと組み込みのSyntaxErrorJSON.parseの両方を処理します。

instanceof行の特定のエラータイプを確認するために(*)を使用する方法を見てください。,

次のように、err.nameを見ることもできます。

// ...// instead of (err instanceof SyntaxError)} else if (err.name == "SyntaxError") { // (*)// ...

instanceofバージョンははるかに優れています。2a9eadcca5″>

PropertyRequiredErrorように、それのサブタイプを作成します。 そして、instanceofチェックは、新しい継承クラスに対して引き続き機能します。 だから、それは将来の証拠です。また、catchが不明なエラーを満たしている場合、(**)行で再スローすることも重要です。, Div id=”c2dfd39931″>

ブロックは、検証と構文エラーの処理方法のみを知っており、他の種類(コード内のタイプミスまたは他の未知のものによる)が落ちる

さらなる継承

ValidationErrorクラスは非常に一般的です。 多くのことが間違っています。 プロパティが存在しないか、間違った形式である可能性があります(ageの文字列値のように)。 不在のプロパティのために、より具体的なクラスPropertyRequiredErrorを作成しましょう。 それは欠落しているプロパティに関する追加情報を運ぶでしょう。,

新しいクラスPropertyRequiredErrorは使いやすいです:プロパティ名を渡す必要があります:new PropertyRequiredError(property)。 人間が読めるmessageは、コンストラクタによって生成されます。

this.namePropertyRequiredErrorコンストラクタは再び手動で割り当てられます。 それは少し面倒になるかもしれません–すべてのカスタムエラークラスでthis.name = <class name>を割り当てます。 割り当てる独自の”基本エラー”クラスを作成することで回避できますthis.name = this.constructor.name。 そして継承すべての当社のカスタムエラーは後からです。,

それをMyErrorと呼びましょう。

MyErrorおよびその他のカスタムエラークラスを簡略化したコードは次のとおりです。

カスタムエラーは、特にValidationError"this.name = ..."コンストラクタの行。

例外のラッピング

上記のコードの関数readUserの目的は、”ユーザーデータを読み取る”ことです。 プロセスに異なる種類のエラーが発生する可能性があります。, 現在、SyntaxErrorValidationErrorがありますが、将来的にはreadUser関数が成長し、おそらく他の種類のエラーを生成する可能性があります。

呼び出すコードreadUserこれらのエラーを処理する必要があります。 現在、ifcatchブロックで複数のifを使用して、クラスをチェックして既知のエラーを処理し、未知のエラーを再スローします。

スキームは次のようなものです。

上記のコードでは、二つのタイプのエラーを見ることができますが、より多くのエラーがある可能性があります。,

もしreadUser関数がいくつかの種類のエラーを生成するなら、私たちは自分自身に尋ねるべきです:私たちは本当にすべてのエラータイプを毎回一つずつチェックしたいのでしょうか?

多くの場合、答えは”いいえ”です:私たちは”すべてのことの上に一つのレベル”になりたいと思います。 しか知りたい場合がありました”データの読み取りエラー”–なぜで起こったく無関係のエラーメッセージを記述します。 または、さらに良いことに、エラーの詳細を取得する方法が必要な場合にのみ必要です。

ここで説明するテクニックは、”例外のラッピング”と呼ばれます。,

  1. 一般的な”データ読み取り”エラーを表すために、新しいクラスReadErrorを作成します。
  2. 関数readUserは、ValidationErrorおよびSyntaxErrorのように、その内部で発生するデータ読み取りエラーをキャッチし、代わりにReadErrorを生成します。li>
  3. ReadErrorオブジェクトは、元のエラーへの参照をcauseプロパティに保持します。,次に、readUserを呼び出すコードは、ReadErrorをチェックするだけで、あらゆる種類のデータ読み取りエラーではありません。 また、エラーの詳細が必要な場合は、causeプロパティをチェックできます。,

    ReadErrorを定義し、readUserおよびtry..catchでの使用を示すコードは次のとおりです。

    上記のコードでは、readUsera5f9b1a45a”>

代わりにエラー(未知のエラーはいつものように再スローされます)。したがって、外側のコードはinstanceof ReadErrorをチェックし、それだけです。 必要な全ての可能なエラーです。,

このアプローチは、”低レベル”の例外を取り込み、それらをReadErrorより抽象的なものに”ラップ”するため、”例外のラップ”と呼ばれます。 で幅広く使用されているオブジェクト指向プログラミング.

Summary

  • Errorおよびその他の組み込みのエラークラスから通常は継承できます。 私たちはちょうど世話をする必要がありますnameプロパティと呼び出すことを忘れないでくださいsuper。li>
  • 特定のエラーをチェックするには、instanceofを使用できます。 また、継承でも機能します。, しかし、時には3rdパーティライブラリからのエラーオブジェクトがあり、そのクラスを取得する簡単な方法はありません。 その後、nameプロパティは、このようなチェックに使用することができます。関数は低レベルの例外を処理し、さまざまな低レベルの例外の代わりに高レベルのエラーを作成します。
  • 例外をラップすることは一般的な手法です。 低レベルの例外は、上記の例ではerr.causeようにそのオブジェクトのプロパティになることがありますが、厳密には必要ありません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です