微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么抛出此错误会导致空白响应,而其他错误则有效?

如何解决为什么抛出此错误会导致空白响应,而其他错误则有效?

我正在使用 nestJS 做一个项目,在为组件开发服务和控制器时,我使用 try - catch 方法处理错误,然后抛出它们。但是,我遇到了一个我无法抛出的错误,因为它会导致一个空白的响应主体,而其他的工作正常。例如:

这是我的 upload.service.ts 中的(工作)函数

async saveFile(body,file) {
    try {
      const uploadRepository = getRepository(Upload);
      const result = await uploadRepository.save({
        // assign properties [...]
      });
      return result;
    } catch (error) {
      unlink(file.path);
      console.log(error);  // Output 1 
      throw new BadRequestException(error);  // Response 1
    }
}

因此,当我故意发出错误请求(通过不在请求正文中发送所需的值)时,我会在控制台中得到以下信息:
输出 1)

QueryFailedError: null value in column "type" of relation "upload" violates not-null constraint
    at new QueryFailedError (%PROJECT_DIRECTORY%\node_modules\typeorm\error\QueryFailedError.js:11:28)
    at PostgresQueryRunner.<anonymous> (%PROJECT_DIRECTORY%\node_modules\typeorm\driver\postgres\PostgresQueryRunner.js:247:31)
    at step (%PROJECT_DIRECTORY%\node_modules\typeorm\node_modules\tslib\tslib.js:141:27)
    at Object.throw (%PROJECT_DIRECTORY%\node_modules\typeorm\node_modules\tslib\tslib.js:122:57)
    at rejected (%PROJECT_DIRECTORY%\node_modules\typeorm\node_modules\tslib\tslib.js:113:69)
    at processticksAndRejections (internal/process/task_queues.js:93:5) {
  length: 393,severity: 'ERROR',code: '23502',detail: 'Failing row contains (51,15,2021-03-23 10:52:59.763387,example.pdf,application/pdf,uploads\\e0f65f7ab43f1c226b37a9463f3a4745,null).',[...]
}

使用 Postman 在响应正文中返回正确的错误
(Response 1)

{
    "message": "null value in column \"type\" of relation \"upload\" violates not-null constraint","length": 393,"name": "QueryFailedError","severity": "ERROR","code": "23502","detail": "Failing row contains (51,null).",[...]
}

现在,这是 upload.service.ts 中的另一个函数

async readFile(res,fileId) {
    try {
      const uploadRepository = getRepository(Upload);
      const found = await uploadRepository.findOne({ id: fileId });

      res.download(found.path,found.originalName);
    } catch (error) {
      console.log(error);  // Output 2
      throw new BadRequestException(error);  // Response 2
    }
  }

当我故意发出错误请求时(通过发送一个 uploadRepository.findOne 找不到的不存在的 ID),我在控制台中得到了这个:
输出 2)

TypeError: Cannot read property 'path' of undefined
    at UploadsService.readFile (%PROJECT_DIRECTORY%\dist\src\components\uploads\uploads.service.js:52:32)
    at processticksAndRejections (internal/process/task_queues.js:93:5)
    at async %PROJECT_DIRECTORY%\node_modules\@nestjs\core\router\router-execution-context.js:46:28
    at async %PROJECT_DIRECTORY%\node_modules\@nestjs\core\router\router-proxy.js:9:17

但是响应正文中有一个空白对象,尽管它使用 Postman 正确具有 400 状态代码
(Response 2)

{}

我可以看出前一个错误,如在 console.log 输出中看到的,有一个具有更多属性的对象。但是,我不知道为什么我无法正确返回后一个错误。我也试过:

throw new NotFoundException({ message: error });
throw new NotFoundException(JSON.stringify(error));
throw new NotFoundException(error.TypeError);

运气不好,因为它们在 message 键中显示一个空对象。

那么,问题是:这些错误有何不同,发送错误的正确方法是什么?

解决方法

有趣的问题让我深入了解 NestJS 源代码。所以,这就是正在发生的事情。

在抛出通过 BadRequestException 传递的 TypeError(注意这是来自 NodeJS,而不是 NestJS)后,BaseExceptionFilter 捕获错误并将其传递给 {{1} (假设您使用的是 express)。在那里,on the following line,他们做到了:

ExpressAdapter

return isObject(body) ? response.json(body) : response.send(String(body)); 变量指的是 body 本身,是一个对象,所以 TypeError 被执行。 问题是,在 response.json(body) 函数内部,传递给它的对象使用 response.json 获取 stringifed。 由于 JSON.stringify 没有可枚举的属性,因此您会得到一个空对象字符串 TypeError

如果您想知道为什么,请查看此SO-post

为了解决这个问题,您可以创建自己的错误对象而不是 {} 并将其传递给 TypeError

,

从他的回答中收到 eol 的输入后,我想知道“我怎么能看到对象的结构是什么”?所以我进入了 Object.getOwnPropertyNames() 方法,该方法“返回一个包含直接在给定对象中找到的所有属性(包括不可枚举属性,使用 Symbol 的属性除外)的数组。 " 添加 console.log(Object.getOwnPropertyNames(error)); 后,输出为 [ 'stack','message' ]

由于 message 属性是一个字符串,所以最终起作用的是:

throw new NotFoundException(error.message);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?