Node.js API:Cloud Storage上传遇路径冲突如何触发报错
解决Cloud Storage上传时路径重复的原子性检查方案
直接利用Google Cloud Storage提供的原子性预条件写入功能,就能彻底避免提前检查带来的竞态问题,同时实现"路径已存在则报错"的需求。
具体做法是在创建写入流时,添加preconditionOpts: { ifGenerationMatch: 0 }配置:
const path = `/uploads/${uuidv4()}.${extname(fileName)}`; const file = bucket.file(path); try { await new Promise((resolve, reject) => data .pipe(file.createWriteStream({ contentType, // 核心配置:仅当文件不存在(generation为0)时才允许写入 preconditionOpts: { ifGenerationMatch: 0 } })) .once('error', reject) .once('finish', resolve), ); } catch (err) { // 捕获路径已存在的错误(错误码通常为412 Precondition Failed) if (err.code === 412) { console.error('文件路径已存在:', path); // 这里可以抛出业务层面的重复错误,或者重试生成新的UUID throw new Error('上传失败:目标路径已存在'); } // 处理其他上传错误 throw err; }
原理说明
- Cloud Storage中,新创建的文件
generation值为0,已存在的文件generation会是一个大于0的整数。 ifGenerationMatch: 0这个预条件会让服务器原子性地检查并写入:只有当目标路径完全不存在时,才执行写入操作;如果路径已存在,直接返回412预条件失败错误。- 这个检查是在Cloud Storage服务器端完成的,完全不存在竞态条件——哪怕多个请求同时尝试写入同一个路径,只有第一个会成功,其余都会触发报错。
内容的提问来源于stack exchange,提问作者Eugene
相关产品推荐
相关产品推荐

