启动Node服务器遇TypeError:ErrorHandler类需用new调用
问题描述
启动Node服务器时出现以下错误:
TypeError: Class constructor ErrorHandler cannot be invoked without 'new' at Layer.handle [as handle_request] (C:\Users\emili\Desktop\shop\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (C:\Users\emili\Desktop\shop\node_modules\express\lib\router\index.js:328:13) at C:\Users\emili\Desktop\shop\node_modules\express\lib\router\index.js:286:9 at Function.process_params (C:\Users\emili\Desktop\shop\node_modules\express\lib\router\index.js:346:12) at next (C:\Users\emili\Desktop\shop\node_modules\express\lib\router\index.js:280:10) at urlencodedParser (C:\Users\emili\Desktop\shop\node_modules\body-parser\lib\types\urlencoded.js:91:7) at Layer.handle [as handle_request] (C:\Users\emili\Desktop\shop\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (C:\Users\emili\Desktop\shop\node_modules\express\lib\router\index.js:328:13) at C:\Users\emili\Desktop\shop\node_modules\express\lib\router\index.js:286:9 at Function.process_params (C:\Users\emili\Desktop\shop\node_modules\express\lib\router\index.js:346:12)
当前ErrorHandler类代码:
class ErrorHandler extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode Error.captureStackTrace(this, this.constructor); } } module.exports = ErrorHandler
导入及使用方式:
const express = require("express"); const ErrorHandler = require("./utils/ErrorHandler"); const app = express(); //rest of the code// app.use(ErrorHandler); module.exports = app;
问题原因与解决方法
原因
Express的app.use()要求传入中间件函数,但你直接传递了ErrorHandler类本身。类必须通过new关键字实例化才能调用,Express尝试直接调用这个类时没有使用new,因此抛出错误。
解决步骤
- 保留
ErrorHandler类作为自定义错误类型,用于抛出特定业务错误 - 单独编写一个符合Express规范的错误处理中间件,专门捕获并处理这类错误
修改后的代码示例:
1. 保持ErrorHandler类不变
class ErrorHandler extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode Error.captureStackTrace(this, this.constructor); } } module.exports = ErrorHandler
2. 调整主文件的使用逻辑
const express = require("express"); const ErrorHandler = require("./utils/ErrorHandler"); const app = express(); // 示例:在业务逻辑中抛出自定义错误 app.get("/api/test", (req, res, next) => { try { // 模拟业务错误场景 if (!req.query.id) { throw new ErrorHandler("缺少必要参数id", 400); } res.send("请求成功"); } catch (err) { next(err); // 将错误传递给错误处理中间件 } }); // 错误处理中间件(必须放在所有路由和普通中间件之后) app.use((err, req, res, next) => { // 设置默认值,处理非自定义错误 const statusCode = err.statusCode || 500; const message = err.message || "服务器内部错误"; // 返回错误响应 res.status(statusCode).json({ success: false, message: message, // 开发环境返回堆栈信息,生产环境建议隐藏 stack: process.env.NODE_ENV === "development" ? err.stack : undefined }); }); module.exports = app;
关键说明
- 错误处理中间件必须定义在所有路由和其他中间件之后,才能捕获到前面流程中抛出的错误
- 手动抛出错误后,必须通过
next(err)将错误传递给中间件,Express会自动识别并调用错误处理逻辑
内容的提问来源于stack exchange,提问作者Emilio Alcántara
相关产品推荐
相关产品推荐

