4-3. 例外処理・ログの考え方
このセクションで学ぶこと
Section titled “このセクションで学ぶこと”- エラーと例外をどう捉えるか
try/catch/finallyの役割- エラーを無視せず、状況を残すことの重要性
- ログがデバッグや運用でどう役立つか
1. なぜ例外処理が必要なのか
Section titled “1. なぜ例外処理が必要なのか”どれだけ丁寧にコードを書いても、現実のシステムでは次のようなことが起こる。
- 入力値が想定外だった
- ファイルや API が取得できなかった
- JSON や数値への変換に失敗した
- 必要なデータが不足していた
つまりプログラムは、常に成功するとは限らない。
そこで必要になるのが、異常系をどう扱うかという考え方である。
その中心にあるのが例外処理である。
正常系入力 → 処理 → 出力
例外発生時入力 → 処理 → エラー発生 ↓ どう扱うか決める例外処理の目的は、「エラーを完全になくすこと」ではなく、起きたときに壊れ方を制御することである。
2. エラーにはいくつか種類がある
Section titled “2. エラーにはいくつか種類がある”初学者は、すべてのエラーを同じものとして捉えがちである。
しかし実際には、性質の違うエラーがある。
| 種類 | 例 | 何が問題か |
|---|---|---|
| 構文エラー | 括弧の閉じ忘れ | コードの形そのものが不正 |
| 実行時エラー / 例外 | 不正な値で処理した | 実行中に問題が起きた |
| 業務ルール違反 | 残高不足、必須項目不足 | 入力はあるがルールを満たさない |
この章では特に、実行中に起きた問題をどう扱うかを中心に学ぶ。
業務ルール違反は概念上は「入力はあるがルールを満たしていない状態」として分けて考えられる。
ただし実際のプログラムでは、その問題を上位へ伝えるために throw を使って Error を投げ、例外として扱うことも多い。
throw とは何か
Section titled “throw とは何か”throw は、「ここでは正常に処理を続けられない」と判断したときに、問題を呼び出し元へ伝えるための構文である。
if (amount > balance) { throw new Error("insufficient balance");}このように書くと、その場で問題を明示し、上位の try / catch 側で受け取って扱える。
つまり throw は、問題を隠すのではなく見える形で伝えるための手段である。
3. try / catch / finally
Section titled “3. try / catch / finally”JavaScript では、例外処理の基本として try / catch / finally を使う。
const text = '{"name":"Sato"}';
try { const data = JSON.parse(text); console.log(data.name);} catch (error) { console.error("Failed to parse JSON:", error.message);} finally { console.log("finished");}たとえば text の末尾の } を消した壊れた JSON に変えると、JSON.parse() が失敗して catch に入る。
| 部分 | 役割 |
|---|---|
try | まず実行してみる処理を書く |
catch | 例外が起きたときの処理を書く |
finally | 成功・失敗にかかわらず最後に行う処理を書く |
どう流れるのか
Section titled “どう流れるのか”try を実行 ↓例外なし ─────→ finally ↓例外あり ↓catch を実行 ↓finallyfinally は、後片付けや終了ログなど「最後に必ず行いたい処理」を置くのに向いている。
4. 例外処理でやってはいけないこと
Section titled “4. 例外処理でやってはいけないこと”例外処理は便利だが、使い方を誤ると問題を隠してしまう。
たとえば次のコードはよくない。
try { riskyOperation();} catch (error) {}catch の中が空だと、問題が起きても「何が起きたのか」が分からなくなる。
これは**サイレントフェイル(黙って失敗する状態)**につながりやすい。
良い基本方針
Section titled “良い基本方針”- 例外を握りつぶさない
- 回復できるなら回復する
- 回復できないなら、少なくとも状況を記録する
- 必要なら上位へエラーを伝える
つまり catch は「とりあえず無視する場所」ではなく、そのエラーにどう向き合うか決める場所である。
5. ログとは何か
Section titled “5. ログとは何か”ログとは、プログラムの中で何が起きたかを記録するメッセージである。
プログラム実行中 ↓[INFO] start order process[WARN] input is missing optional field[ERROR] failed to save orderログが重要なのは、エラーが起きた瞬間に人が見ていないことが多いからである。
後から調査するとき、ログは「何が起きたか」を知る大事な手掛かりになる。
よくあるログレベル
Section titled “よくあるログレベル”| レベル | 使いどころ |
|---|---|
INFO | 正常な進行や開始・終了の記録 |
WARN | すぐ停止はしないが、注意したい状態 |
ERROR | 処理失敗や例外など、明確な問題 |
良いログに必要なもの
Section titled “良いログに必要なもの”良いログには、次の要素がある。
- 何をしていたか
- どの入力や ID を扱っていたか
- 成功したのか失敗したのか
- エラーならメッセージは何か
たとえば、単に failed とだけ出すより、[ERROR] withdraw failed: insufficient balance のほうが原因を追いやすい。
6. ログに書いてよいこと、避けるべきこと
Section titled “6. ログに書いてよいこと、避けるべきこと”ログは多ければよいわけではない。
何でも出すと、重要な情報が埋もれたり、機密情報を漏らしたりする危険がある。
書くと役立つもの
Section titled “書くと役立つもの”- 処理名
- 対象 ID
- 入力値の要約
- エラーメッセージ
- 処理の成否
そのまま出さないほうがよいもの
Section titled “そのまま出さないほうがよいもの”- パスワード
- アクセストークン
- 個人情報の全文
- 不要に大量の内部データ
ログは「調査しやすさ」と「安全性」の両方を意識する必要がある。
7. 例外処理とログはどう組み合わさるか
Section titled “7. 例外処理とログはどう組み合わさるか”例外処理とログは別のものだが、実務ではよく一緒に使う。
処理開始 ↓問題発生 ↓catch で状況を受け止める ↓ログへ記録する ↓必要なら安全なメッセージを返すここで重要なのは、「ユーザーへ見せる内容」と「開発者が調査に使う内容」を分けることだ。
ユーザーには分かりやすい説明、開発者には原因を追える情報が必要になる。
8. 初学者が混同しやすい点
Section titled “8. 初学者が混同しやすい点”catch したら問題解決、ではない
Section titled “catch したら問題解決、ではない”catch は、エラーを受け取っただけである。
そこから「回復する」「ログを残す」「処理を止める」などを決める必要がある。
ログはデバッグ用の独り言ではない
Section titled “ログはデバッグ用の独り言ではない”ログは、あとで他の人が読んでも意味が分かる必要がある。
そのため、文脈のない短いメッセージより、状況が分かる文のほうがよい。
例外処理は乱用しない
Section titled “例外処理は乱用しない”すべてを巨大な try / catch で囲むと、どこで何が失敗したのか見えにくくなる。
必要な範囲で扱うことが大切である。
| キーワード | 説明 |
|---|---|
| 例外 | 実行中に起きた問題を表すもの |
throw | 問題を上位へ伝えるために例外を投げる構文 |
try | まず実行してみる処理を書く場所 |
catch | 例外が起きたときの処理を書く場所 |
finally | 最後に必ず実行したい処理を書く場所 |
| サイレントフェイル | エラーを黙って握りつぶしてしまう状態 |
| ログ | 何が起きたかを記録するメッセージ |
INFO / WARN / ERROR | ログの重要度を表す目安 |
次のステップ
Section titled “次のステップ”演習問題 に取り組んで理解を確認しよう。
理解できたら 4-4. アルゴリズムとデータ構造入門 へ進もう。