- Promiseエラー捕捉は「非同期処理の落とし穴を確実に拾い上げるための必須テクニック」
- Promise エラーが try/catch で捕捉できない理由を理解する(最重要)
- ステップ1:Promise のエラーを .catch() で捕捉する(基本)
- ステップ2:async/await のエラーは try/catch で捕捉できる
- ステップ3:Promise エラーを共通化する(業務で必須)
- ステップ4:Promise の未処理拒否(Unhandled Rejection)を捕捉する
- ステップ5:Promise エラーを整形して読みやすくする
- ステップ6:Promise エラーを共通 Logger に流す
- ステップ7:業務で使える Promise エラー捕捉ユーティリティ(完成版)
- ステップ8:業務での活用例
- 深掘り:Promise エラー捕捉が重要な理由
- まとめ:Promise エラー捕捉は「非同期処理の安全性を守るための必須技術」
Promiseエラー捕捉は「非同期処理の落とし穴を確実に拾い上げるための必須テクニック」
Promise は便利ですが、初心者が必ずつまずくポイントがあります。
try/catchでは Promise のエラーを捕捉できない場合がある.catch()を書き忘れると Unhandled Rejection(未処理拒否) が発生する- 非同期処理の中で発生した例外が 静かに消える
- 本番環境で原因不明のエラーが発生し、ログが残らない
業務システムでは、Promise エラーを確実に捕捉し、 ログに残し、必要なら監視ツールに送信する仕組みが必須です。
ここでは、ステップバイステップで Promise エラー捕捉の考え方 → 実装 → 強化 → 業務テンプレート までを丁寧に解説します。
Promise エラーが try/catch で捕捉できない理由を理解する(最重要)
例:try/catch が効かないケース
try {
Promise.reject(new Error("API失敗"));
} catch (e) {
console.log("捕捉できない");
}
JavaScriptこれは catch に入らない ため、エラーが消えます。
理由は、Promise のエラーは 非同期的に発生するため、 try/catch の同期的な例外捕捉では拾えないからです。
ステップ1:Promise のエラーを .catch() で捕捉する(基本)
fetch("/api/user")
.then(res => res.json())
.catch(e => {
console.error("Promiseエラー:", e);
});
JavaScript重要ポイント
.catch()を書き忘れると Unhandled Rejection になる- Promise チェーンの最後に必ず
.catch()を付ける習慣が重要
ステップ2:async/await のエラーは try/catch で捕捉できる
async function run() {
try {
const res = await fetch("/api/user");
return await res.json();
} catch (e) {
console.error("async/await エラー:", e);
}
}
JavaScript重要ポイント
- async/await は Promise を「同期的に扱える」ため try/catch が効く
- ただし、await を書き忘れると捕捉できない
ステップ3:Promise エラーを共通化する(業務で必須)
毎回 .catch() を書くのは非効率なので、 Promise を安全に実行するユーティリティを作ります。
async function safePromise(promise, context = "") {
try {
const result = await promise;
return { ok: true, value: result };
} catch (e) {
console.error(`[ERROR] [${context}]`, e);
return { ok: false, error: e };
}
}
JavaScript使用例
const res = await safePromise(fetch("/api/user"), "UserAPI");
if (!res.ok) return;
console.log(res.value);
JavaScriptステップ4:Promise の未処理拒否(Unhandled Rejection)を捕捉する
Promise の .catch() を書き忘れると発生するエラーです。
ブラウザの場合
window.onunhandledrejection = function(event) {
console.error("[UNHANDLED REJECTION]", event.reason);
};
JavaScriptNode.js の場合
process.on("unhandledRejection", (reason) => {
console.error("[UNHANDLED REJECTION]", reason);
});
JavaScript重要ポイント
- 本番環境では必ず設定する
- これがないと「静かに消えるエラー」が発生する
ステップ5:Promise エラーを整形して読みやすくする
function formatPromiseError(e) {
return {
name: e?.name,
message: e?.message,
stack: e?.stack,
};
}
JavaScriptステップ6:Promise エラーを共通 Logger に流す
function logPromiseError(e, context) {
Logger.error(formatPromiseError(e), context);
}
JavaScriptステップ7:業務で使える Promise エラー捕捉ユーティリティ(完成版)
export const PromiseErrorUtil = {
format(e) {
return {
name: e?.name,
message: e?.message,
stack: e?.stack,
...Object.keys(e || {}).reduce((acc, key) => {
acc[key] = e[key];
return acc;
}, {}),
};
},
async run(promise, context = "") {
try {
const value = await promise;
return { ok: true, value };
} catch (e) {
Logger.error(this.format(e), context);
return { ok: false, error: this.format(e) };
}
},
initGlobalHandler() {
if (typeof window !== "undefined") {
window.onunhandledrejection = (event) => {
Logger.error(this.format(event.reason), "UnhandledRejection");
};
}
if (typeof process !== "undefined") {
process.on("unhandledRejection", (reason) => {
Logger.error(this.format(reason), "UnhandledRejection");
});
}
},
};
JavaScriptステップ8:業務での活用例
API 呼び出し
const res = await PromiseErrorUtil.run(fetch("/api/user"), "UserAPI");
JavaScriptDB 操作
const result = await PromiseErrorUtil.run(db.query("SELECT * FROM users"), "DBQuery");
JavaScriptバッチ処理
const batch = await PromiseErrorUtil.run(runBatch(), "SalesBatch");
JavaScriptグローバルハンドラの初期化
PromiseErrorUtil.initGlobalHandler();
JavaScript深掘り:Promise エラー捕捉が重要な理由
1. 非同期エラーは try/catch では拾えない場合がある
Promise の特性を理解しないと、エラーが消えます。
2. Unhandled Rejection は本番で致命的
静かに消えるため、障害調査が困難になります。
3. 監視ツールとの連携が容易になる
整形された Promise エラーは外部サービスに送信しやすいです。
4. エラー処理の統一でコードが読みやすくなる
業務ロジックがシンプルになり、保守性が向上します。
まとめ:Promise エラー捕捉は「非同期処理の安全性を守るための必須技術」
Promise エラー捕捉を正しく扱うことで、次のメリットが得られます。
- 非同期エラーを確実に捕捉できる
- Unhandled Rejection を防げる
- ログ形式が統一される
- 障害調査が高速化する
- 監視ツールとの連携が容易になる
Promise は便利ですが、 エラー捕捉を正しく設計しないと危険な落とし穴になります。
共通 Logger や try/catch 共通化と組み合わせることで、 業務システムの安定性が大きく向上します。
