如何正确封装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
相关产品推荐
相关产品推荐

