NestJS中BadRequestException参数在捕获打印时未生效的问题
NestJS中抛出BadRequestException后,SuperTest E2E测试无法获取自定义错误信息
问题场景
我的NestJS服务中,当user未定义时会抛出BadRequestException:
if (user == undefined) { throw new BadRequestException('foo', 'bar') }
在E2E测试中,我通过封装后的SuperTest调用接口:
const apiClient = () => { return supertest(app.getHttpServer()) } try { await apiClient() .post('/api/do/something') .set('Accept', 'application/json') .send(/* 测试数据 */) .expect('Content-Type', /json/) .expect(201) } catch (e) { console.log(`error: ${e}`) }
控制台仅输出状态码错误,看不到自定义的错误信息:
error: Error: expected 201 "Created", got 400 "Bad Request"
按NestJS文档描述,BadRequestException的参数应该会被保留,但我没有配置自定义异常处理,尝试多种调用方式都无法获取到'foo'和'bar',请问怎么解决?
解决方法
1. 调整SuperTest的测试逻辑,先获取响应再断言
SuperTest的链式expect()方法在断言失败时,抛出的错误只会包含状态码差异,不会返回接口实际的响应内容。你可以先发送请求拿到响应对象,再分别断言状态码和响应体:
try { const response = await apiClient() .post('/api/do/something') .set('Accept', 'application/json') .send(/* 测试数据 */) // 断言状态码 expect(response.status).toBe(400); // 断言自定义错误信息 expect(response.body.message).toBe('foo'); expect(response.body.error).toBe('Bad Request'); // NestJS默认错误类型 expect(response.body.statusCode).toBe(400); } catch (e) { console.log(`error: ${e}`); // 打印响应体(如果请求成功但断言失败) if (e.response) { console.log('response body:', e.response.body); } }
2. 正确使用BadRequestException构造函数
NestJS的BadRequestException构造函数参数有两种常用写法:
- 单参数:直接传错误消息字符串,响应体中
message字段就是该字符串 - 双参数:第一个参数是响应体内容(可以是字符串或对象),第二个参数是日志用的错误描述(不会返回给客户端)
如果需要返回多个自定义字段,应该传入一个对象:
if (user == undefined) { // 返回自定义结构的响应体 throw new BadRequestException({ message: 'foo', customInfo: 'bar' }); }
此时测试中可以断言response.body.customInfo为'bar'。
3. 确认全局异常处理未被覆盖
检查你的main.ts文件,确保没有注册自定义的全局异常过滤器,导致默认的异常处理逻辑被覆盖:
// 避免这类未配置的自定义过滤器代码 // app.useGlobalFilters(new CustomExceptionFilter());
默认情况下,NestJS会将BadRequestException转换为包含statusCode、message、error字段的JSON响应。
内容的提问来源于stack exchange,提问作者titusmagnus
相关产品推荐
相关产品推荐

