今日の1日の始まりは猫が布団に入ってきたことでした。GENYAです。
tl;dr
APIの想定内(ロジック)のエラーの場合はハンドリングして、
想定外の場合は例外としてsentryにthrowする。
実際の動きの確認 => https://codesandbox.io/s/try-catch-throw-9ild7
課題感
エラーハンドリングの動きが認知されていなかったので、
実際に動くものを参考に挙動を確認する。
今回は sentry が window.onerrrorを監視していて、
ロジカルなエラーのハンドリングとその扱いをどうすべきかということが議論になったので確認していく。
ロジック内のハンドリングをどう制御するか
APIの接続時など外部への接続でエラーが起きたことを想定、
そのときに throwされたこととする。
この場合、ケースとしてはこんな感じになる。
1. try内でAPIコール
2. エラー発火
3. catchに入ってきてハンドリング処理を実行
4. finallyが実行
5. エラーが発火してもしなくても、最後の到達が呼び出される
export const ロジック内のハンドリング = () => {
try {
throw new Error("test"); // 1 エラー発火
} catch (エラー情報) {
console.log("ロジック内のハンドリングをする", エラー情報); // 2
} finally {
console.log("finally called"); // 3
}
console.log("ロジック内のハンドリング 到達"); // 4
};
ハンドリングしたが例外が起きたケース
- try内でAPIコール
- エラー発火
- catchに入ってきてハンドリング処理を実行
- ハンドリングしきれなかったものをthrowする
- finallyが実行
- sentryへ例外エラーが送られる
export const ロジック外のエラーを再throw = () => {
try {
throw new Error("test");
} catch (エラー情報) {
console.log("ロジック外の例外は更にthrowする sentryが発火");
throw エラー情報;
} finally {
console.log("finally called ロジック外のエラーを再throw");
}
console.log("ロジック外のエラーを再throw 終了"); // 実行されない
};
まとめ
観測すべきエラーはどういうものか、それはロジカルなエラーなのか、例外のケースなのかで判断をすると良いように思う。
ここで言うロジカルなエラーというのはバックエンドのIFの定義に含まれる status code や 独自のエラーの仕組みの定義を意味する。
それ以外の例外が起きたケースというのは計測して、ハンドリングし、対処方法を考えていく動きをする。
例えばサーバーが500を返すような場合であっても、
フロント側のハンドリングは 500をハンドリングする共通処理を実行を想定していれば、
それはsentryで計測する必要はないと考える。
多段のtryを書く場合のハンドリングも↓に用意したので興味がある人は codesandboxで挙動を確認してみてください。
追記
よくある実装でやる奴を書いておきます。
export const よくある実装でやる奴を書いておく = async () => {
ローディングを表示する()
try {
const {response的な何か} = await APIをリクエスト()
受け取った値を料理する(response的な何か)
} catch (エラー情報) {
// API固有のハンドリング
if (エラー情報.status === 400) {
ダイアログを表示する('入力内容に誤りがあります')
} else if (エラー情報.status === 451) {
ダイアログを表示する('政府による検閲によりコンテンツが表示できません')
} else {
共通のエラーハンドリング関数もしくはアクション(エラー情報)
}
} finally {
ローディングを非表示する()
}
};