Express自定义错误类全局异常处理报错求助
Express全局错误处理失效问题
作为Express新手,在使用自定义错误类和中间件做全局错误处理时遇到问题:在控制器中调用next(new AppError())抛出错误后,错误没有进入errorMiddleware,而是直接输出错误栈信息。
自定义错误类 app.error.ts
export class AppError extends Error { statusCode: number; constructor(message: string, statusCode: number) { super(message); this.statusCode = statusCode; Error.captureStackTrace(this, this.constructor); } }
控制器 chat.controller.ts
export const chat = async (req: Request, res: Response, next: NextFunction) => { const { prompt } = req.body; if (!prompt) { // 此处使用AppError类时出现报错 return next(new AppError("Prompt is required", 400)); } try { // 异步任务... const responseText = 'Response Text'; const response: IResponse<string> = { success: true, data: responseText, }; return sendResponse(res, response, HttpStatus.OK); } catch (error: any) { // catch中使用同样出现问题 return next(new AppError(error.message, 500)); } };
报错信息
Error: Prompt is required at E:\Projects\vibe-ai\vibe-ai-backend\src\controllers\chat.controller.ts:11:28 at Generator.next (<anonymous>) at E:\Projects\vibe-ai\vibe-ai-backend\src\controllers\chat.controller.ts:8:71 at new Promise (<anonymous>) at __awaiter (E:\Projects\vibe-ai\vibe-ai-backend\src\controllers\chat.controller.ts:4:12) at chat (E:\Projects\vibe-ai\vibe-ai-backend\src\controllers\chat.controller.ts:9:79) at Layer.handle [as handle_request] (E:\Projects\vibe-ai\vibe-ai-backend\node_modules\express\lib\router\layer.js:95:5) at next (E:\Projects\vibe-ai\vibe-ai-backend\node_modules\express\lib\router\route.js:149:13) at Route.dispatch (E:\Projects\vibe-ai\vibe-ai-backend\node_modules\express\lib\router\route.js:119:3) at Layer.handle [as handle_request] (E:\Projects\vibe-ai\vibe-ai-backend\node_modules\express\lib\router\layer.js:95:5)
主应用配置
import express, { Request, Response, NextFunction } from "express"; import { config } from "dotenv"; import HttpStatus from "http-status-codes"; config(); import { errorMiddleware } from "./src/middlewares"; import { chatRouter } from "./src/routes"; import { AppError } from "./src/utils"; const app = express(); const PORT = process.env.PORT || 6050; app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(此处为控制器路由); app.all("*", (req: Request, res: Response, next: NextFunction) => { return next(new AppError("Route not found", HttpStatus.NOT_FOUND)); }); app.use(errorMiddleware); app.listen(PORT, () => console.log(`App is listening at port http://localhost:${PORT}`) );
错误中间件 error.middleware.ts
const errorMiddleware = (err: AppError, req: Request, res: Response) => { err.statusCode = err.statusCode || 500; err.message = err.message || SystemConstants.WENT_WRONG; const response: IResponse<undefined> = { success: false, message: err.message, stack: err.stack, }; return res.status(err.statusCode).json(response); };
已尝试操作
- 在多处添加日志,但错误抛出后未进入错误中间件,仅在AppError类中能看到日志
- 尝试使用
throw new AppError(),但了解到异步场景下该方式无效
问题原因及解决方法
1. 错误中间件参数不完整
Express的错误处理中间件必须包含4个参数:err, req, res, next,缺少next参数会导致Express不识别这是一个错误处理中间件,直接跳过它。
修改error.middleware.ts:
const errorMiddleware = (err: AppError, req: Request, res: Response, next: NextFunction) => { err.statusCode = err.statusCode || 500; err.message = err.message || SystemConstants.WENT_WRONG; const response: IResponse<undefined> = { success: false, message: err.message, stack: err.stack, }; return res.status(err.statusCode).json(response); };
2. 确认路由注册顺序
确保错误中间件是最后注册的中间件,必须放在所有路由和其他中间件之后。同时检查此处为控制器路由是否正确注册了chatRouter,比如:
app.use('/chat', chatRouter);
3. 验证错误中间件接收情况
在错误中间件开头添加日志,确认是否接收到错误:
const errorMiddleware = (err: AppError, req: Request, res: Response, next: NextFunction) => { console.log('进入错误中间件:', err); // 添加日志验证 err.statusCode = err.statusCode || 500; err.message = err.message || SystemConstants.WENT_WRONG; const response: IResponse<undefined> = { success: false, message: err.message, stack: err.stack, }; return res.status(err.statusCode).json(response); };
4. 异步函数错误兜底
如果使用Express 4版本,异步控制器的未捕获错误需要手动传递给next,你当前的try/catch写法是正确的,但要确保所有异步操作都被包裹在try块中。
内容的提问来源于stack exchange,提问作者Varun Savaliya
相关产品推荐
相关产品推荐

