/**
* APIルートの catch 節から呼ぶロギングヘルパー。
*
* クライアントへ返す `ApiError` を**そのまま**受け取るのが要点。
* ログ側で code / message を組み立て直すとレスポンスとズレるため、
* 同一オブジェクトから読む形にして構造的に防ぐ(docs/logging-design.md §3)。
* 生の例外メッセージは `error_message` に入らない(定型文のみ)。
*/
import type pino from "pino";
import { emitTo, logger } from "@/lib/logger";
import type { ApiError } from "@/lib/types";
export interface ApiErrorLogParams {
/** 実際のパス。`/api/v1/...` のような架空のパスを書かない */
route: string;
method: string;
/** クライアントへ返すものと同一の body */
body: ApiError;
status: number;
/** 例外そのもの。pino の err シリアライザに渡す */
err: unknown;
}
/**
* 出力先を差し替えられる版。
* 全APIルートのエラー経路が通る関数なので、実出力をテストで検証できる接合部を用意する
* (`emitTo` / `logEvent` と同じ形)。設定を二重に書かないため target を渡すだけにする。
*/
export function logApiErrorTo(
target: pino.Logger,
params: ApiErrorLogParams
): void {
emitTo(
target,
"error",
{
event: "api.error",
route: params.route,
method: params.method,
error_code: params.body.error.code,
error_message: params.body.error.message,
http_status: params.status,
},
params.err
);
}
export function logApiError(params: ApiErrorLogParams): void {
logApiErrorTo(logger, params);
}