You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

取消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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:10:33