Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 38x 38x 38x 38x 9x 11x 2x 10x 4x 5x 18x 18x 12x 11x 11x 1x 1x 6x 18x 2x 2x 4x | import type { Response } from "express";
/**
* アプリケーション内で使用するカスタムエラーの基底クラス。
* HTTPステータスコードを保持する `statusCode` プロパティを追加し、
* APIのレスポンスで適切なステータスを返せるように設計されています。
*/
export class CustomError extends Error {
statusCode: number;
constructor(message: string, statusCode: number = 500) {
super(message);
this.name = this.constructor.name;
this.statusCode = statusCode;
Error.captureStackTrace(this, this.constructor);
}
}
/**
* 認証関連のエラー(例: トークン無効、権限不足)を示すクラス。
* HTTPステータスコードは `401 Unauthorized` がデフォルトです。
*/
export class AuthenticationError extends CustomError {
constructor(
message: string = "Authentication failed",
statusCode: number = 401,
) {
super(message, statusCode);
}
}
/**
* リクエストの入力値検証エラー(例: 必須パラメータの欠如、フォーマット不正)を示すクラス。
* HTTPステータスコードは `400 Bad Request` がデフォルトです。
*/
export class ValidationError extends CustomError {
constructor(message: string = "Validation failed", statusCode: number = 400) {
super(message, statusCode);
}
}
/**
* 要求されたリソースが見つからない場合のエラーを示すクラス。
* HTTPステータスコードは `404 Not Found` がデフォルトです。
*/
export class NotFoundError extends CustomError {
constructor(
message: string = "Resource not found",
statusCode: number = 404,
) {
super(message, statusCode);
}
}
/**
* Fitbit APIとの通信中に発生したエラーを示すクラス。
* 外部API起因の問題であることを明確にします。
* デフォルトのステータスコードは `500 Internal Server Error` とし、クライアント側には詳細を伝えないようにします。
*/
export class FitbitApiError extends CustomError {
constructor(message: string = "Fitbit API error", statusCode: number = 500) {
super(message, statusCode);
}
}
/**
* サポートされていないHTTPメソッドでエンドポイントが呼び出されたことを示すエラー。
* HTTPステータスコードは `405 Method Not Allowed` がデフォルトです。
*/
export class MethodNotAllowedError extends CustomError {
constructor(
message: string = "Method Not Allowed",
statusCode: number = 405,
) {
super(message, statusCode);
}
}
/**
* 統一的なエラーハンドリングを行うユーティリティ関数。
* 発生したエラーをログに出力し、クライアントに適切なHTTPステータスコードとメッセージを返します。
* セキュリティ上の理由から、500以上のエラーや予期せぬエラーの詳細はクライアントに開示せず、
* 汎用的なメッセージを返します。
*
* @param res Expressのレスポンスオブジェクト
* @param error 発生したエラーオブジェクト
*/
export const handleError = (res: Response, error: unknown): void => {
// エラーの詳細をサーバーログに出力 (重要)
console.error("Error caught in handler:", error);
// カスタムエラーの場合
if (error instanceof CustomError) {
// 400番台のエラー(クライアントエラー)はメッセージを返しても安全
if (error.statusCode < 500) {
res.status(error.statusCode).json({ error: error.message });
return;
}
// 500番台のエラーは詳細を隠蔽
res
.status(error.statusCode)
.json({ error: "An internal server error occurred." });
return;
}
// 特定のエラーメッセージパターンに対する互換性維持
// errorがErrorオブジェクトの場合はmessageを取得、それ以外(文字列など)はString変換
const errorMessage = error instanceof Error ? error.message : String(error);
if (
errorMessage.includes("ID token") ||
errorMessage.includes("Unauthorized")
) {
res.status(401).json({ error: "Unauthorized" });
return;
}
// その他の予期せぬエラー
res.status(500).json({ error: "An internal server error occurred." });
};
|