- エラーをサーバーへ送信することは「障害を確実に記録し、運用チームへ“見える化”するための必須技術」
- エラー送信の目的は「開発者が本番環境の障害を正確に把握すること」
- ステップ1:送信するエラー情報を整形する(最重要)
- ステップ2:エラーを JSON 化する(送信のための必須処理)
- ステップ3:サーバーへ送信する関数を作る(基本版)
- ステップ4:送信処理を try/catch で安全化する(重要)
- ステップ5:エラー発生時に自動送信するユーティリティを作る(完成版)
- ステップ6:グローバルエラーと組み合わせて自動送信する
- ステップ7:再送防止(同じエラーを大量送信しないための対策)
- ステップ8:業務で使えるエラー送信ユーティリティ(完成版)
- ステップ9:業務での活用例
- 深掘り:なぜエラーをサーバーへ送信する必要があるのか
- まとめ:エラー送信は「本番運用の生命線」
エラーをサーバーへ送信することは「障害を確実に記録し、運用チームへ“見える化”するための必須技術」
業務システムでは、エラーをサーバーへ送信する仕組みが必ず必要になります。 理由は明確で、次のような問題を防ぐためです。
- クライアント側だけのログでは本番障害を再現できない
- ユーザー環境で発生したエラーを開発者が把握できない
- 監視ツール(Sentry、Datadog、CloudWatch 等)と連携できない
- 障害の傾向分析ができない
- 重大エラーをリアルタイムで検知できない
つまり、エラー送信は 「本番運用の生命線」 です。
ここでは、初心者でも理解しやすいように、 エラー整形 → JSON 化 → 送信 → 再送制御 → 業務テンプレート までをステップバイステップで解説します。
エラー送信の目的は「開発者が本番環境の障害を正確に把握すること」
エラー送信は次の情報を含むべきです。
- エラーコード(分類)
- エラーメッセージ(概要)
- スタックトレース(原因特定の最重要情報)
- 追加情報(APIレスポンス、入力値、環境情報など)
- 発生コンテキスト(どの処理で起きたか)
- タイムスタンプ
- ユーザー環境情報(ブラウザ、OS、URL など)
これらをまとめて送信することで、 障害調査のスピードが圧倒的に向上します。
ステップ1:送信するエラー情報を整形する(最重要)
まずはエラーを構造化します。
function formatErrorForServer(error, context = "") {
return {
timestamp: new Date().toISOString(),
context,
code: error.code || "SYS-001",
name: error.name,
message: error.message,
stack: error.stack,
extra: Object.keys(error).reduce((acc, key) => {
if (!["code", "name", "message", "stack"].includes(key)) {
acc[key] = error[key];
}
return acc;
}, {}),
env: {
url: location.href,
userAgent: navigator.userAgent,
},
};
}
JavaScriptステップ2:エラーを JSON 化する(送信のための必須処理)
function stringifyError(errorObj) {
try {
return JSON.stringify(errorObj);
} catch {
return JSON.stringify({ message: "Unserializable error" });
}
}
JavaScriptステップ3:サーバーへ送信する関数を作る(基本版)
async function sendErrorToServer(errorObj) {
await fetch("/error/report", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: stringifyError(errorObj),
});
}
JavaScriptステップ4:送信処理を try/catch で安全化する(重要)
エラー送信自体が失敗する可能性があるため、 送信処理も安全に実行します。
async function safeSendError(errorObj) {
try {
await sendErrorToServer(errorObj);
} catch (e) {
console.warn("エラー送信に失敗しました:", e);
}
}
JavaScriptステップ5:エラー発生時に自動送信するユーティリティを作る(完成版)
export const ErrorReporter = {
async report(error, context = "") {
const formatted = formatErrorForServer(error, context);
await safeSendError(formatted);
}
};
JavaScriptステップ6:グローバルエラーと組み合わせて自動送信する
ブラウザ
window.onerror = (message, source, lineno, colno, error) => {
ErrorReporter.report(error || new Error(message), "GlobalError");
};
window.onunhandledrejection = (event) => {
ErrorReporter.report(event.reason, "UnhandledRejection");
};
JavaScriptNode.js
process.on("uncaughtException", (error) => {
ErrorReporter.report(error, "UncaughtException");
});
process.on("unhandledRejection", (reason) => {
ErrorReporter.report(reason, "UnhandledRejection");
});
JavaScriptステップ7:再送防止(同じエラーを大量送信しないための対策)
本番では同じエラーが大量発生することがあります。 そのため、一定時間内の重複送信を防ぎます。
const sentErrors = new Set();
function shouldSend(errorObj) {
const key = errorObj.code + errorObj.message;
if (sentErrors.has(key)) return false;
sentErrors.add(key);
setTimeout(() => sentErrors.delete(key), 5000); // 5秒で解除
return true;
}
JavaScript送信前にチェックします。
async function safeSendError(errorObj) {
if (!shouldSend(errorObj)) return;
try {
await sendErrorToServer(errorObj);
} catch (e) {
console.warn("エラー送信に失敗しました:", e);
}
}
JavaScriptステップ8:業務で使えるエラー送信ユーティリティ(完成版)
export const ErrorReporter = {
format(error, context = "") {
return {
timestamp: new Date().toISOString(),
context,
code: error.code || "SYS-001",
name: error.name,
message: error.message,
stack: error.stack,
extra: Object.keys(error).reduce((acc, key) => {
if (!["code", "name", "message", "stack"].includes(key)) {
acc[key] = error[key];
}
return acc;
}, {}),
env: {
url: location.href,
userAgent: navigator.userAgent,
},
};
},
async send(errorObj) {
try {
await fetch("/error/report", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: stringifyError(errorObj),
});
} catch (e) {
console.warn("エラー送信に失敗しました:", e);
}
},
async report(error, context = "") {
const formatted = this.format(error, context);
if (shouldSend(formatted)) {
await this.send(formatted);
}
},
};
JavaScriptステップ9:業務での活用例
API 呼び出しでの障害送信
try {
await fetch("/api/user");
} catch (e) {
ErrorReporter.report(e, "UserAPI");
}
JavaScriptバッチ処理の異常終了
try {
runBatch();
} catch (e) {
ErrorReporter.report(e, "SalesBatch");
}
JavaScriptグローバルエラー送信
ErrorReporter.report(error, "GlobalError");
JavaScript深掘り:なぜエラーをサーバーへ送信する必要があるのか
1. 本番環境の障害は再現できないことが多い
ユーザー環境のブラウザ・OS・ネットワーク状況は再現困難です。
2. ローカルログだけでは原因特定が不可能
本番で起きたエラーは、開発者の PC では再現できません。
3. 監視ツールと連携するための基盤になる
Sentry、Datadog、CloudWatch などはサーバー送信が前提です。
4. 障害の傾向分析ができる
どのエラーが多いか、どの機能で発生しているかを分析できます。
5. 重大障害をリアルタイムで検知できる
サーバー側で通知を飛ばすことができます。
まとめ:エラー送信は「本番運用の生命線」
エラー送信を正しく設計することで、次のメリットが得られます。
- 本番環境の障害を確実に記録できる
- 原因特定が高速化する
- 監視ツールとの連携が容易になる
- 障害の傾向分析ができる
- 重大障害をリアルタイムで検知できる
エラー整形・JSON 化・グローバルエラー捕捉と組み合わせることで、 業務システムの品質が劇的に向上します。

