Node.js注册接口:参数验证失败时返回JSON而非HTML的问题
问题分析
当使用无效信息注册时,验证中间件抛出了ApiError,但由于缺少全局错误处理中间件,Express默认返回了HTML格式的错误页面,而非预期的JSON响应。注册路由中的try/catch仅能捕获register函数内部的异常,无法处理中间链中前置验证步骤抛出的错误。
解决方案
1. 编写全局错误处理中间件
创建两个中间件:将普通错误转为ApiError的错误转换器,以及统一返回JSON格式错误的错误处理器:
const httpStatus = require('http-status'); const ApiError = require('./utils/ApiError'); // 替换为你的ApiError实际路径 // 错误转换器:将非ApiError类型的错误转换为标准ApiError const errorConverter = (err, req, res, next) => { let error = err; if (!(error instanceof ApiError)) { const statusCode = error.statusCode || httpStatus.INTERNAL_SERVER_ERROR; const message = error.message || httpStatus[statusCode]; error = new ApiError(statusCode, message, false, err.stack); } next(error); }; // 错误处理器:统一返回JSON格式的错误响应 const errorHandler = (err, req, res, next) => { const { statusCode, message } = err; // 生产环境下隐藏非业务错误详情 const response = { code: statusCode, message: process.env.NODE_ENV === 'production' && !err.isOperational ? '服务器内部错误' : message, ...(process.env.NODE_ENV === 'development' && { stack: err.stack }), }; if (process.env.NODE_ENV === 'development') { console.error(err); } res.status(statusCode).json(response); }; module.exports = { errorConverter, errorHandler };
2. 在Express应用中注册中间件
确保错误处理中间件在所有路由之后注册,这样才能捕获所有路由和中间件抛出的错误:
const express = require('express'); const { errorConverter, errorHandler } = require('./middlewares/error'); // 替换为你的中间件路径 const userRoutes = require('./routes/user'); // 替换为你的路由路径 const app = express(); // 解析请求体等基础中间件 app.use(express.json()); app.use(express.urlencoded({ extended: true })); // 注册业务路由 app.use('/api/users', userRoutes); // 注册错误处理中间件 app.use(errorConverter); app.use(errorHandler); app.listen(3000, () => { console.log('服务器运行在端口3000'); });
3. 验证效果
现在使用无效信息注册时,验证中间件抛出的ApiError会被全局错误处理器捕获,返回如下JSON格式响应:
{ "code": 400, "message": "\"phoneNumber\" length must be at least 10 characters long" }
内容的提问来源于stack exchange,提问作者John Oliver
相关产品推荐
相关产品推荐

