/** * Utilities for handling SSR errors gracefully */ /** * Extract HTTP status code from an error object. * Looks for a `status` property that is a number or parseable string. * Returns 500 if no valid status found. */ export function getErrorStatus(error: unknown): number { if (error && typeof error === 'object' && 'status' in error) { const status = (error as { status: unknown }).status; if (typeof status === 'number' && status >= 100 && status < 600) { return status; } if (typeof status === 'string') { const parsed = parseInt(status, 10); if (!isNaN(parsed) && parsed >= 100 && parsed < 600) { return parsed; } } } return 500; } /** * Escape HTML special characters to prevent XSS */ export function escapeHtml(str: string): string { return str .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } export interface RenderErrorPageOptions { /** Show stack trace in output */ showStack?: boolean; /** Additional hint message to display */ hint?: string; /** Badge text to display (e.g., "DEV MODE") */ badge?: string; } /** * Render an HTML error page for SSR failures */ export function renderErrorPage( error: unknown, url: string, statusCode: number, options: RenderErrorPageOptions = {}, ): string { const errorMessage = error instanceof Error ? error.message : String(error); const stack = error instanceof Error ? error.stack : undefined; const { showStack = false, hint, badge } = options; return `
Error rendering: ${escapeHtml(url)}
${showStack && stack ? `${escapeHtml(stack)}` : ''}
${hint ? `${escapeHtml(hint)}
` : ''}