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

如何正确封装fs.unlink返回Promise 解决删除文件出错无返回问题

问题根因
  • Promise回调逻辑不严谨:unlink回调内触发reject(error)后没有加return终止执行,虽然Promise状态一旦变更就不会二次修改,但后续冗余的resolve(true)属于无效逻辑,存在隐患。
  • 错误处理逻辑完全错位:你封装的Promise在删除失败时是通过reject抛出异常,而非resolve(false)返回失败状态。使用await调用时,一旦删除出错,reject的异常会直接抛出,不会给isFileRemoved赋值,后续的if判断代码根本不会执行。
  • if判断逻辑本身不符合预期:删除成功时Promise返回值为true,!isFileRemoved等价于false,本来就不会进入错误抛出分支,这个分支本身是为false返回值设计的,但你的代码从未返回过false。
修复方案

1. 修正Service层代码

优先推荐直接使用Node.js官方提供的Promise版fs API,无需手动封装Promise,减少出错概率:

import { unlink } from 'fs/promises';
import path from 'path';

public async removeUserImage(
   user: User,
): Promise<boolean> {
   // 用path.join拼接路径,避免跨平台斜杠、多余斜杠问题
   const pathToRemoveImage = path.join('src/public/uploads', user.image_url);
   await unlink(pathToRemoveImage);
   return true;
 }

如果要保留手动封装Promise的写法,记得在reject后加return终止执行:

import { unlink } from 'fs';
import path from 'path';

public removeUserImage(
   user: User,
): Promise<boolean> {
   const pathToRemoveImage = path.join('src/public/uploads', user.image_url);

   return new Promise((resolve, reject) => {
       unlink(pathToRemoveImage, (error) => {
          if (error) {
            reject(error);
            return; // 终止后续逻辑执行
          }
          resolve(true);
       });
    });
 }

2. 修正Controller层错误捕获逻辑

因为删除失败时Promise是抛出异常而非返回false,所以需要用try/catch捕获错误,而非判断返回值:

try {
  await this._userService.removeUserImage(user);
  // 文件删除成功后的后续业务逻辑写在这里
} catch (error) {
  throw new InternalServerErrorException(
    'Error occurred while trying to remove file.',
  );
}

不建议把错误通过resolve(false)的方式返回,异步操作通过reject抛出错误是JS的标准约定,更符合通用错误处理逻辑。

内容的提问来源于stack exchange,提问作者RAHUL KUNDU

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 11:03:20