Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
33 lines
959 B
TypeScript
33 lines
959 B
TypeScript
import type { Request, Response, NextFunction } from "express";
|
|
|
|
interface AppError extends Error {
|
|
statusCode?: number;
|
|
details?: unknown;
|
|
}
|
|
|
|
/** Create a typed error with status code. */
|
|
export function createError(message: string, statusCode: number, details?: unknown): AppError {
|
|
const err: AppError = new Error(message);
|
|
err.statusCode = statusCode;
|
|
err.details = details;
|
|
return err;
|
|
}
|
|
|
|
/** Express error-handling middleware — must be mounted last. */
|
|
export function errorHandler(
|
|
err: AppError,
|
|
_req: Request,
|
|
res: Response,
|
|
_next: NextFunction,
|
|
): void {
|
|
const status = err.statusCode || 500;
|
|
const isDev = process.env.NODE_ENV !== "production";
|
|
|
|
console.error(`[ERROR] ${status} ${err.message}`, isDev ? err.stack : "");
|
|
|
|
res.status(status).json({
|
|
error: err.message || "Internal server error",
|
|
...(err.details ? { details: err.details } : {}),
|
|
...(isDev && err.stack ? { stack: err.stack } : {}),
|
|
});
|
|
}
|