取消NestJS文件下载时触发报错问题求助
解决NestJS文件下载时用户取消操作导致的服务器报错问题
问题原因
当用户在下载过程中取消操作,浏览器会主动断开与服务器的HTTP连接,此时Node.js的文件读取流在向响应对象写入数据时会触发ECONNRESET(连接重置)错误。由于未对流的错误事件做处理,这个错误会被NestJS的全局异常处理机制捕获并记录为服务器报错。
解决方案
方案1:为文件流添加错误监听(推荐)
直接在文件读取流上监听error事件,静默处理连接中断类的错误,同时保留对其他异常的抛出:
@Get(':encodedname') public async downloadSingle( @Param('encodedname') encodedname: string, @Res({ passthrough: true }) res: Response, ): Promise<StreamableFile> { const { fileInfo } = await this.uploadsService.getFileInfo(encodedname); const file = createReadStream( join(process.cwd(), `./uploads/${fileInfo.filename}`), ); // 处理流错误,仅忽略连接中断类异常 file.on('error', (err) => { if (err.code !== 'ECONNRESET') { throw err; } }); res.set({ 'Content-Type': fileInfo.mimetype, 'Content-Disposition': `${ fileInfo.mimetype.startsWith('image') || fileInfo.mimetype.startsWith('audio') || fileInfo.mimetype.startsWith('video') ? 'inline' : 'attachment' }; filename="${fileInfo.originalname}"`, 'Content-Length': fileInfo.size, }); return new StreamableFile(file); }
方案2:使用全局异常过滤器
如果多个下载接口都存在这个问题,可以创建全局异常过滤器,统一处理连接中断错误:
import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common'; import { Request, Response } from 'express'; @Catch(Error) export class DownloadConnResetFilter implements ExceptionFilter { catch(exception: Error, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); // 识别连接重置错误,静默处理 if (exception.code === 'ECONNRESET') { response.end(); return; } // 其他异常按默认逻辑返回错误响应 const request = ctx.getRequest<Request>(); response.status(500).json({ statusCode: 500, timestamp: new Date().toISOString(), path: request.url, message: exception.message, }); } }
将过滤器注册到模块或单个接口:
- 模块全局注册:在
AppModule的providers数组中添加{ provide: APP_FILTER, useClass: DownloadConnResetFilter } - 单个接口使用:在
downloadSingle方法上添加@UseFilters(DownloadConnResetFilter)装饰器
补充说明
startsWith比indexOf == 0更直观,建议替换原有判断逻辑- 仅忽略
ECONNRESET错误,避免掩盖其他真实的服务器异常(如文件不存在、权限问题等)
内容的提问来源于stack exchange,提问作者goldnite
相关产品推荐
相关产品推荐

