Improve 500 error logging with actual error details and correct log levels
pino-http was logging 500s at INFO level with a generic "failed with status code 500" message. Now 500s log at ERROR level and include the actual error (message, stack, name) via res.locals handoff from the error handler. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,9 @@ export function errorHandler(
|
|||||||
? { message: err.message, stack: err.stack, name: err.name }
|
? { message: err.message, stack: err.stack, name: err.name }
|
||||||
: { raw: err };
|
: { raw: err };
|
||||||
|
|
||||||
|
// Attach the real error so pino-http can include it in its response log
|
||||||
|
res.locals.serverError = errObj;
|
||||||
|
|
||||||
logger.error(
|
logger.error(
|
||||||
{ err: errObj, method: req.method, url: req.originalUrl },
|
{ err: errObj, method: req.method, url: req.originalUrl },
|
||||||
"Unhandled error: %s %s — %s",
|
"Unhandled error: %s %s — %s",
|
||||||
|
|||||||
@@ -2,8 +2,20 @@ import path from "node:path";
|
|||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import pino from "pino";
|
import pino from "pino";
|
||||||
import { pinoHttp } from "pino-http";
|
import { pinoHttp } from "pino-http";
|
||||||
|
import { readConfigFile } from "../config-file.js";
|
||||||
|
import { resolveDefaultLogsDir, resolveHomeAwarePath } from "../home-paths.js";
|
||||||
|
|
||||||
const logDir = path.resolve(process.cwd(), ".paperclip", "logs");
|
function resolveServerLogDir(): string {
|
||||||
|
const envOverride = process.env.PAPERCLIP_LOG_DIR?.trim();
|
||||||
|
if (envOverride) return resolveHomeAwarePath(envOverride);
|
||||||
|
|
||||||
|
const fileLogDir = readConfigFile()?.logging.logDir?.trim();
|
||||||
|
if (fileLogDir) return resolveHomeAwarePath(fileLogDir);
|
||||||
|
|
||||||
|
return resolveDefaultLogsDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
const logDir = resolveServerLogDir();
|
||||||
fs.mkdirSync(logDir, { recursive: true });
|
fs.mkdirSync(logDir, { recursive: true });
|
||||||
|
|
||||||
const logFile = path.join(logDir, "server.log");
|
const logFile = path.join(logDir, "server.log");
|
||||||
@@ -32,10 +44,22 @@ export const logger = pino({
|
|||||||
|
|
||||||
export const httpLogger = pinoHttp({
|
export const httpLogger = pinoHttp({
|
||||||
logger,
|
logger,
|
||||||
|
customLogLevel(_req, res, err) {
|
||||||
|
if (err || res.statusCode >= 500) return "error";
|
||||||
|
if (res.statusCode >= 400) return "warn";
|
||||||
|
return "info";
|
||||||
|
},
|
||||||
customSuccessMessage(req, res) {
|
customSuccessMessage(req, res) {
|
||||||
return `${req.method} ${req.url} ${res.statusCode}`;
|
return `${req.method} ${req.url} ${res.statusCode}`;
|
||||||
},
|
},
|
||||||
customErrorMessage(req, res) {
|
customErrorMessage(req, res) {
|
||||||
return `${req.method} ${req.url} ${res.statusCode}`;
|
return `${req.method} ${req.url} ${res.statusCode}`;
|
||||||
},
|
},
|
||||||
|
customProps(_req, res) {
|
||||||
|
const serverError = (res as any).locals?.serverError;
|
||||||
|
if (serverError) {
|
||||||
|
return { serverError };
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user