
導入
プログラミングを始めたばかりの頃は、「エラーが出たら直す」を繰り返しているうちに、だんだん怖くなってきます。自分が想定していない場面で止まったり、途中まで処理が進んだまま中途半端な状態になったりするからです。
そこで役に立つ考え方がtry/catchです。try/catch を使うと、「失敗するかもしれない処理」を前提にして、失敗したときの振る舞いを決められます。結果として、プログラムが落ちにくくなり、原因調査もしやすくなります。
この記事では、言語ごとの細かい文法には踏み込まず、try/catch の考え方、使いどころ、throw や finally の役割、メリットとデメリット、そして例外設計のコツを初心者向けに整理します。
try/catch を一言でいうと(簡単なサンプルコードつき)
try/catch は、「失敗しうる処理」を安全に扱うための仕組みです。
- try:まずは実行してみる(失敗する可能性がある)
- catch:失敗したときに“捕まえて”、代わりの処理をする(復旧・通知・記録など)
JavaScript でいうと、雰囲気はこうです。
try {
// 失敗するかもしれない処理
const user = JSON.parse('{"name":"Kohno"}');
console.log("ユーザー名:", user.name);
} catch (e) {
// 失敗したときの対応
console.log("読み込みに失敗しました(JSONが壊れているかも)");
}
この例では、JSON.parse() が失敗したときに catch に移動します。catch があることで、そこで止まらずに「失敗したときの動き」を決められます。
“エラー”と“例外”の違い
try/catch を理解するときに、まず整理しておきたいのが「エラー」と「例外」です。
- エラー:うまくいかない状況の総称(広い言葉)
- 例外:プログラムの実行中に「このまま続けるのは危険だから、通常の流れを中断して知らせる」ための仕組み
例外が起きると、多くの場合はその場の処理が中断され、上の呼び出し元へと伝わっていきます。どこかでキャッチ(catch)されなければ、プログラム全体が止まることもあります。
つまり try/catch は、例外が起きたときに「止め方」や「立て直し方」を決める道具、という位置づけです。
try/catch が必要になる典型パターン
try/catch を書くべき場面は、だいたい共通しています。ポイントは「自分の努力だけでは100%コントロールできない」処理です。
外部要因が絡む処理
- ファイルを読む/書く(ファイルが無い、権限がない、壊れている)
- ネットワーク通信(回線が不安定、サーバーが落ちている)
- API 呼び出し(相手の仕様変更、タイムアウト、制限)
- DB 接続(接続できない、ロック、負荷)
- OSや環境依存(パスが違う、メモリ不足 など)
入力データが不確かな処理
- ユーザー入力(空欄、フォーマット違い、想定外の文字)
- 外部から受け取ったデータ(JSON が壊れている、欠損している)
ここで大事なのは、try/catch は「何でも解決する魔法」ではないことです。たとえば、設計ミスやロジックのバグを try/catch で黙らせると、根本原因が見えなくなって逆に危険です。try/catch は起こりうる失敗を受け止めるための仕組みであって、失敗の原因を消すものではありません。
try catchの書き方(throw / finally も含めて)
ここでは言語別の細かい差ではなく、JavaScript を例にしながら「どう考えて書くか」を説明します。よく使う要素は次の3つです。
- try:通常ルート(成功したら進む処理)
- catch:例外が起きたときのルート(復旧・通知・記録)
- finally:成功/失敗に関係なく必ず実行したい処理(後片付け)
そして、意図的に失敗扱いにしたいときに使うのがthrowです。
try と catch の基本形
try {
const n = Number("123");
console.log(n * 2);
} catch (e) {
console.log("計算できませんでした");
}
ポイントは、「例外が起きた瞬間に try の残りは飛ばされて catch に移る」ことです。
throw(自分で例外を発生させる)
「この値はおかしい」「このまま続けたくない」を自分で判断して、例外として扱いたいときがあります。そういうときに throw を使います。
function parseAge(text) {
const age = Number(text);
if (Number.isNaN(age)) {
throw new Error("年齢が数値ではありません");
}
if (age < 0) {
throw new Error("年齢がマイナスです");
}
return age;
}
try {
const age = parseAge("abc");
console.log("年齢:", age);
} catch (e) {
console.log("入力エラー:", e.message);
}
throw を使うと、「エラーっぽい値(NaNなど)」を放置して後で爆発させるのではなく、早めに失敗として扱って、catch に流す設計ができます。
finally(成功しても失敗しても必ずやる後片付け)
失敗したときでも「必ず最後にやりたい処理」があります。たとえば「ローディング表示を消す」「一時的な状態を戻す」「ログの締めをする」などです。そこで finally を使います。
let loading = false;
try {
loading = true;
console.log("処理開始。loading =", loading);
const data = JSON.parse("broken json");
console.log(data);
} catch (e) {
console.log("失敗しました:", e.message);
} finally {
loading = false;
console.log("後片付け。loading =", loading);
}
finally は、try が成功しても、catch に入っても、最後に必ず実行されます。「途中で失敗しても UI 状態だけは戻したい」みたいなケースで特に効きます。
メリット・デメリット
メリット
- プログラムが落ちにくくなる:例外を放置すると途中で止まります。try/catch で「止め方」を設計できます。
- ユーザーに説明できる:失敗時に状況と次の行動を案内できます。
- 原因調査がしやすくなる:いつ・どこで・何が起きたかを記録しやすくなります。
- 後片付けを確実にできる:成功・失敗に関係なく状態を戻せます。
- 失敗前提で設計できる:「失敗したらどうする?」が自然に考えられるようになります。
デメリット
- 例外の握りつぶしが起きやすい:catch して何も残さないと、静かに失敗し続けることがあります。
- try の範囲が広すぎると原因が分かりにくい:とりあえず全部 try は、デバッグを難しくします。
- 本当のバグを隠してしまう:本来は入力チェックやロジック修正で直すべき問題が見えにくくなります。
- コードが読みにくくなる:例外ルートが増えるほど分岐が増え、見通しが悪くなります。
- 例外を通常フローにしてしまう誘惑がある:頻繁に起こる分岐は if などで扱う方が自然です。
失敗時に catch で何をすればいい?
catch の中身はケースによりますが、初心者はまず「型」を持っておくと迷いません。
- 伝える:利用者に状況と次の行動を案内する
- 記録する:調査できるようにログを残す
- 片付ける:途中状態を戻す、リソースを解放する
- 復旧する:リトライ、代替手段、デフォルト値に切り替える
- 引き継ぐ:ここで直せないなら上位へ伝える
全部を一度にやる必要はありませんが、最低でも「何が起きたか分かる情報を残す」は意識しておくと強いです。
例外設計のコツ
try/catch を「書ける」だけだと、乱用して逆に辛くなります。ここからは、初心者が事故りにくい考え方のコツです。
- try は最小範囲にする:失敗する可能性がある部分だけに絞ると、原因が追いやすくなります。
- catch したら最低限情報を残す:握りつぶさず、後で追える形にします。
- if で防げるものは if で防ぐ:入力チェックなど「想定内」は通常の分岐で扱う方が自然です。
- ここで復旧できるかで置き場所を決める:復旧できる場所でキャッチし、無理なら上位へ引き継ぎます。
- ユーザー向けと開発者向けを分ける:案内と調査情報を混ぜないようにします。
まとめ
try/catch は「失敗するかもしれない」を前提にして、失敗時の動きを設計するための仕組みです。外部要因が絡む処理ほど try/catch の価値が大きくなります。
一方で、乱用すると原因が隠れたり、読みにくくなったりします。try は最小範囲、catch では最低限の記録、if で済むものは if、という感覚を持つだけでも事故は減ります。
次の記事では、言語別の具体的な記法(書き方の違い、よくある罠、代表例)をまとめると理解が深まります。

