概要
TypeScriptでカスタムエラーの3つの実装方法を記載しました。
自分ならXXXなのでこれを選ぶ、あるいはもっといい方法があるというようなご意見をいただきたいです。
前提条件
- Javascript(TypeScript)では極力例外を投げるのは避けるべきとは思っている
- サポート対象ブラウザはChrome,FireFox,Safariの最新版のみ。デバイスはPC, タブレット, スマートフォン。
- TypeScriptを使用したSPA. ソースコード50000行ほど、ファイル数680 今後2倍くらいになりそう
- フロントエンド監視にはSentryを使用している
- JavascriptのErrorを拡張して,エラー種別の判別とSentryでのバグトラッキングに活かしたい(エラーコードを設けたり、エラー種別によってエラーハンドリングを変えたり)
実装方法
1. Errorをimplementsするクラスを作成する
class ApplicationError implements Error { public name = 'ApplicationError'; constructor(public message: string, public code: ApplicationErrorCode) { } toString() { return `${this.name}: ${this.message}`; } }
メリット
-
アプリケーションの例外とJSの例外が分別できる
引用:
ネイティブのError 型は聖域として扱い、この種の例外を決してスローしないようにしよう。
カスタム例外をApplicationError クラスのサブクラスとして作成すれば、本当に例外的な状況においてコードの外側で使用するためにError型を取っておくことができる。
デメリット
- スタックトレースが取れない
- 子クラスを作るたびにnameを書かないといけない(何らかの方法で解決できるのかもしれないが自分は分からない)
2. Errorをextendsするクラスを作成する
class FooError extends Error { constructor(m: string) { super(m); // Set the prototype explicitly. Object.setPrototypeOf(this, FooError.prototype); } sayHello() { return "hello " + this.message; } }
出典 Extending built-ins like Error, Array, and Map may no longer work
メリット
- スタックトレースが取れる
デメリット
Object.setPrototypeOf
を忘れたり誤ったりするとinstance instanceof FooError
がfalseになる- TypeScript, Javascriptの仕様変更によって壊れる可能性が1より高い(実際にTypeScript2.1で壊れた)
3. Errorをカスタムするのではなく,throwをカスタムしてすべてErrorを使用する
/** * フレームワークエラーを発生させます。 * * @private * @param code {Number} エラーコード * @param msgParam {Any[]} フォーマットパラメータ * @param detail {Any} 追加のデータ(内容はAPIごとに異なる) */ function throwFwError(code, msgParam, detail) { ..... if (code) { e.code = code; } if (detail) { e.detail = detail; } throw e; }
出典 hifive - HTML5企業Webシステムのための開発プラットフォーム - hifive
メリット
- 全てのエラーはErrorなのでインターフェースが統一されている
- codeがenumであればdiscriminated unionsによって型の推論ができる
デメリット
- TypeScriptだとグローバルのError型定義を拡張しなければならない
- 使用する側が気を付けなければならない
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/04/27 06:12
退会済みユーザー
2018/04/27 06:14