2026-02-16 13:31:58 -06:00
|
|
|
import type { Request, Response, NextFunction } from "express";
|
|
|
|
|
import { ZodError } from "zod";
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
import { HttpError } from "../errors.js";
|
2026-02-16 13:31:58 -06:00
|
|
|
|
2026-03-06 11:41:06 -06:00
|
|
|
export interface ErrorContext {
|
|
|
|
|
error: { message: string; stack?: string; name?: string; details?: unknown; raw?: unknown };
|
|
|
|
|
method: string;
|
|
|
|
|
url: string;
|
|
|
|
|
reqBody?: unknown;
|
|
|
|
|
reqParams?: unknown;
|
|
|
|
|
reqQuery?: unknown;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-07 15:19:03 -06:00
|
|
|
function attachErrorContext(
|
|
|
|
|
req: Request,
|
|
|
|
|
res: Response,
|
|
|
|
|
payload: ErrorContext["error"],
|
|
|
|
|
rawError?: Error,
|
|
|
|
|
) {
|
|
|
|
|
(res as any).__errorContext = {
|
|
|
|
|
error: payload,
|
|
|
|
|
method: req.method,
|
|
|
|
|
url: req.originalUrl,
|
|
|
|
|
reqBody: req.body,
|
|
|
|
|
reqParams: req.params,
|
|
|
|
|
reqQuery: req.query,
|
|
|
|
|
} satisfies ErrorContext;
|
|
|
|
|
if (rawError) {
|
|
|
|
|
(res as any).err = rawError;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-16 13:31:58 -06:00
|
|
|
export function errorHandler(
|
|
|
|
|
err: unknown,
|
2026-02-20 07:11:06 -06:00
|
|
|
req: Request,
|
2026-02-16 13:31:58 -06:00
|
|
|
res: Response,
|
|
|
|
|
_next: NextFunction,
|
|
|
|
|
) {
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
if (err instanceof HttpError) {
|
2026-03-05 13:28:26 -06:00
|
|
|
if (err.status >= 500) {
|
2026-03-07 15:19:03 -06:00
|
|
|
attachErrorContext(
|
|
|
|
|
req,
|
|
|
|
|
res,
|
|
|
|
|
{ message: err.message, stack: err.stack, name: err.name, details: err.details },
|
|
|
|
|
err,
|
|
|
|
|
);
|
2026-03-05 13:28:26 -06:00
|
|
|
}
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
res.status(err.status).json({
|
|
|
|
|
error: err.message,
|
|
|
|
|
...(err.details ? { details: err.details } : {}),
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-16 13:31:58 -06:00
|
|
|
if (err instanceof ZodError) {
|
|
|
|
|
res.status(400).json({ error: "Validation error", details: err.errors });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-07 15:19:03 -06:00
|
|
|
const rootError = err instanceof Error ? err : new Error(String(err));
|
|
|
|
|
attachErrorContext(
|
|
|
|
|
req,
|
|
|
|
|
res,
|
|
|
|
|
err instanceof Error
|
2026-03-06 11:41:06 -06:00
|
|
|
? { message: err.message, stack: err.stack, name: err.name }
|
2026-03-07 15:19:03 -06:00
|
|
|
: { message: String(err), raw: err, stack: rootError.stack, name: rootError.name },
|
|
|
|
|
rootError,
|
|
|
|
|
);
|
2026-03-05 07:39:05 -06:00
|
|
|
|
2026-02-16 13:31:58 -06:00
|
|
|
res.status(500).json({ error: "Internal server error" });
|
|
|
|
|
}
|