我试图做什么
我想使用NestJs将文件内容流式传输到http客户端。
目前,我使用
StreamableFile
所述对象
in the NestJs docs
问题是
找不到服务器上的文件时
-
我的解决方案发送了一个
400 Bad Request
而不是404
-
更重要的是
错误包含服务器端文件的路径
不幸的是,我还不知道如何在将错误发送到客户端之前捕获它。
NestJs控制器中的端点
@Get('coordinates/:processId')
@Header('Content-Type', 'application/json')
public async getCoordinates(
@Param('processId') processId: string
): Promise<StreamableFile> {
return this.getFileContentStream(
join(
this.getProcessingDir(processId),
"coordinates.json"
)
);
}
还有我的
getFileContentStream
做必要事情的方法
private getFileContentStream(path: string): Promise<StreamableFile> {
return new Promise((resolve, reject) => {
// throw new BadRequestException("test");
const errorHandler = (err: Error) => {
const myErr = new Error(`Error reading data`, { cause: err });
Logger.error(getErrorMessageWithCausedByParts(myErr));
reject(myErr);
}
const stream = createReadStream(path);
stream.on('error', errorHandler);
// stream.prependListener('error', errorHandler)
//stream.on('end', () => Logger.verbose(`End of streaming '${path}'`));
resolve(new StreamableFile(stream))
})
}
这是错误日志
[Nest] 262768 - 16.08.2023, 21:12:16 ERROR Error: Error reading data
at ReadStream.errorHandler (...\src\lib\controllers\fem-results.controller.ts:40:31)
at ReadStream.emit (node:events:525:35)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
[caused by] Error: ENOENT: no such file or directory, open '...\processing\04921742-c563-4a2d-96d1-ef8786daf014\info.json'
[Nest] 262768 - 16.08.2023, 21:12:16 DEBUG GET /api/calc/fem-results/info/04921742-c563-4a2d-96d1-ef8786daf014 400 193 - 239.489 ms
[Nest] 262768 - 16.08.2023, 21:12:16 ERROR [ExpressAdapter] ENOENT: no such file or directory, open '...\processing\04921742-c563-4a2d-96d1-ef8786daf014\info.json'
最后一行中的错误也会发送到客户端。文件的路径是绝对的。我只是把它缩短了。。。
我读过
“您可以监听此事件以防止抛出错误的默认行为”
在里面
this SO answer
而且
this
看起来我可以过滤它,但要么我做错了,要么当流与StreamableFile一起使用时不是这样。
我不知道ReadStream何时尝试访问该文件,但我想只有在解析了promise之后才能访问,因此拒绝可能不起作用。但我相信有一些方法可以防止错误文本泄露到客户端。
我必须使用某种管道来过滤掉这个错误吗?或者你知道另一种方法吗?