| この記事の要点 |
|---|
|
try / catch(同期 + await)
try {
const data = JSON.parse(invalidJson);
} catch (error) {
console.error("エラー:", error.message);
}
// async / await の場合
async function fetchData() {
try {
const res = await fetch("/api/data");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (error) {
console.error("失敗:", error);
return null;
}
}
finally で後片付け
async function operation() {
let loading = true;
try {
const data = await fetch("/api");
return data;
} catch (error) {
console.error(error);
return null;
} finally {
loading = false; // 必ず実行される
console.log("完了");
}
}
Promise の catch
fetch("/api/data")
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.error("失敗:", error))
.finally(() => console.log("完了"));
// 複数 Promise
Promise.all([fetch("/api/a"), fetch("/api/b")])
.then(([a, b]) => { ... })
.catch(error => console.error("どれかが失敗:", error));
// 並列で個別エラー処理
Promise.allSettled([fetch("/api/a"), fetch("/api/b")])
.then(results => {
results.forEach(r => {
if (r.status === "fulfilled") {
console.log("成功:", r.value);
} else {
console.error("失敗:", r.reason);
}
});
});
グローバルなエラーハンドラ
① window.onerror(同期エラー + リソース読み込み)
// 古典的な方法
window.onerror = function (message, source, lineno, colno, error) {
console.error("グローバルエラー:", { message, source, lineno, colno, error });
// サーバに送信
fetch("/api/log/error", {
method: "POST",
body: JSON.stringify({ message, source, lineno, colno, stack: error?.stack })
});
return true; // true を返すとブラウザのデフォルトエラー処理を抑止
};
// addEventListener 版(複数ハンドラを登録可能)
window.addEventListener("error", (event) => {
console.error("グローバルエラー:", event.error);
event.preventDefault(); // ブラウザのコンソール出力を抑止
});
② unhandledrejection(Promise の捕捉漏れ)
// .catch() を書き忘れた Promise を拾う
window.addEventListener("unhandledrejection", (event) => {
console.error("未処理の Promise エラー:", event.reason);
event.preventDefault();
});
// 発生例
async function bad() {
await fetch("/invalid"); // 404 → .catch() なし
JSON.parse("invalid"); // SyntaxError
}
bad(); // ← unhandledrejection が発火
③ リソース読み込みエラー(img, script, link)
// img や script の load エラーは bubble しない
// → addEventListener で capture: true にする
window.addEventListener("error", (event) => {
if (event.target !== window) {
// リソースエラー (img の 404 等)
console.error("リソース読み込み失敗:", event.target.src || event.target.href);
}
}, true); // ← capture フェーズで拾う
React のエラーバウンダリ
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.error("React error:", error, info);
// サーバ送信
}
render() {
if (this.state.hasError) {
return <h1>エラーが発生しました</h1>;
}
return this.props.children;
}
}
// 使い方
<ErrorBoundary>
<App />
</ErrorBoundary>
Vue.js のエラーハンドラ
// Vue 3
const app = createApp(App);
app.config.errorHandler = (err, instance, info) => {
console.error("Vue error:", err, info);
// info: 'render', 'mounted hook', etc.
};
// Vue 2
Vue.config.errorHandler = function (err, vm, info) {
console.error("Vue error:", err, info);
};
// コンポーネント単位
export default {
errorCaptured(err, vm, info) {
console.error("Captured:", err);
return false; // false なら親に伝播しない
}
};
カスタム Error クラス
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
class NetworkError extends Error {
constructor(message, statusCode) {
super(message);
this.name = "NetworkError";
this.statusCode = statusCode;
}
}
// 使用
try {
if (!email) throw new ValidationError("メール必須", "email");
if (!response.ok) throw new NetworkError("API 失敗", response.status);
} catch (error) {
if (error instanceof ValidationError) {
showFieldError(error.field, error.message);
} else if (error instanceof NetworkError) {
showNetworkError(error.statusCode);
} else {
console.error("予期しないエラー:", error);
}
}
エラーログをサーバ送信
function logErrorToServer(error, context = {}) {
fetch("/api/log/error", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: error.message,
stack: error.stack,
url: location.href,
userAgent: navigator.userAgent,
timestamp: new Date().toISOString(),
...context
})
}).catch(() => { /* ログ送信失敗は無視 */ });
}
// グローバルハンドラから呼ぶ
window.addEventListener("error", (e) => logErrorToServer(e.error || new Error(e.message)));
window.addEventListener("unhandledrejection", (e) => logErrorToServer(e.reason));
エラー監視ツール
本格運用なら専用サービスを使う:
- Sentry: 無料枠あり、ベスト
- Rollbar
- Datadog RUM
- New Relic Browser
// Sentry の例
import * as Sentry from "@sentry/browser";
Sentry.init({
dsn: "https://...@sentry.io/...",
environment: "production",
tracesSampleRate: 0.1
});
// 自動で window.onerror / unhandledrejection を捕捉
// 手動送信
Sentry.captureException(new Error("カスタムエラー"));
Sentry.captureMessage("情報メッセージ", "info");
注意点
- try/catch は同期と await のみ: Promise の .then() 内のエラーは届かない
- 非同期コールバック:
setTimeout(fn, 0)内のエラーは外の try/catch で拾えない - イベントリスナー内のエラー: ハンドラ内で try/catch するか、グローバル onerror に任せる
- cross-origin script のエラー: 詳細情報が "Script error" としか出ない →
crossorigin="anonymous"属性 + サーバ CORS 設定
関連記事
子ページ
子ページはありません
同階層のページ
- 基本事項
- HTMLへの埋め込み
- 変数
- 可変変数
- 定数
- データ型
- キャスト
- エスケープ文字
- 配列
- 演算子
- 代入の際の注意点
- 条件分岐
- 繰り返し処理
- クラスとインスタンス
- コンストラクタ
- 関数
- スーパーグローバル変数
- スコープ
- staticについて
- yieldについて
- ファイルのアップロード方法
- DB接続方法
- SQL実行方法
- カプセル化の具体例
- 継承の構文
- オーバーライド
- ポリモーフィズム(多様性)の具体例
- 抽象クラス・メソッドの構文と具体例
- GET通信
- try catchで全てのエラーを拾う方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38