import { Request, Response, NextFunction } from 'express'; import { logger } from '../utils/logger.js'; import { ERROR_CODES, HTTP_STATUS } from '@media-manager/shared'; export class AppError extends Error { public readonly statusCode: number; public readonly code: string; public readonly isOperational: boolean; constructor( message: string, statusCode: number = HTTP_STATUS.INTERNAL_SERVER_ERROR, code: string = ERROR_CODES.UNKNOWN, isOperational: boolean = true ) { super(message); this.statusCode = statusCode; this.code = code; this.isOperational = isOperational; Error.captureStackTrace(this, this.constructor); } } export function errorHandler( err: Error | AppError, _req: Request, res: Response, _next: NextFunction ): void { if (err instanceof AppError) { logger.warn(`AppError: ${err.message}`, { code: err.code, statusCode: err.statusCode }); res.status(err.statusCode).json({ success: false, error: { code: err.code, message: err.message, }, }); return; } // 未知错误 logger.error('Unexpected error:', err); res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ success: false, error: { code: ERROR_CODES.UNKNOWN, message: process.env.NODE_ENV === 'production' ? 'Internal server error' : err.message, }, }); } // 异步处理器包装 export function asyncHandler( fn: (req: Request, res: Response, next: NextFunction) => Promise ) { return (req: Request, res: Response, next: NextFunction) => { Promise.resolve(fn(req, res, next)).catch(next); }; }