Something went wrong. Try again.
AtAuth
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586/** * Error Handling Utilities * * Provides safe error responses that don't leak internal details. * Express 5 automatically forwards async errors to the error handler. */
/** * Standard error response format. */export interface ErrorResponse { error: string; message: string;}
/** * HTTP error with status code and machine-readable error code. * Thrown from route handlers and caught by the global error middleware. */export class HttpError extends Error { constructor( public readonly statusCode: number, public readonly code: string, message: string ) { super(message); this.name = 'HttpError'; }}
/** * Convenience factory functions for common HTTP errors. */export const httpError = { badRequest: (code: string, message: string) => new HttpError(400, code, message), unauthorized: (code: string, message: string) => new HttpError(401, code, message), forbidden: (code: string, message: string) => new HttpError(403, code, message), notFound: (code: string, message: string) => new HttpError(404, code, message), conflict: (code: string, message: string) => new HttpError(409, code, message), internalServerError: (code: string, message: string) => new HttpError(500, code, message),};
/** * Sanitize an error for client response. * Logs the full error server-side but returns a safe message to clients. * * @param error - The caught error * @param context - Context for logging (e.g., "Token verify") * @returns Safe error message for client response */export function sanitizeError(error: unknown, context: string): string { // Log full error details server-side for debugging console.error(`${context} error:`, error);
// In development, return more details for debugging // In production, return a generic message if (process.env.NODE_ENV === 'development') { if (error instanceof Error) { // Even in dev, don't expose stack traces or sensitive paths return error.message.replace(/\/[^\s:]+/g, '[path]'); } }
// Generic message that doesn't leak implementation details return 'An internal error occurred. Please try again later.';}
/** * Create a safe 500 error response. * * @param errorCode - Machine-readable error code * @param error - The caught error * @param context - Context for logging * @returns Error response object */export function internalError( errorCode: string, error: unknown, context: string): ErrorResponse { return { error: errorCode, message: sanitizeError(error, context), };}