应通过 eslint 规则(如 @typescript-eslint/no-floating-promises)+ ci 强制检查 + typescript 严格编译选项来管控裸 await 错误处理,而非依赖 ci/cd 拦截;需白名单豁免顶层 await、iife 等合理场景,并可结合 sonarqube 追踪改进趋势。

不能靠 CI/CD “强行拦截”裸 await,因为 await 本身不是语法错误,ESLint 或 TypeScript 编译器也不会报错——它合法、常见、且在顶层或 async 函数中完全合理。所谓“无 try-catch 的裸 await”,本质是**代码健壮性与错误处理约定问题**,需通过静态检查 + 规则约束 + 团队共识来落地,而非在流水线里用黑盒方式“拦截”。
核心思路:用 ESLint 插件识别未被错误处理的 Promise 链
真正可检测、可阻断的是“await 后未做错误处理”的模式,例如:
- await 调用后直接使用返回值,但没处理可能的 rejection
- 多个 await 连续写,中间无任何 catch/finally 或 .catch() 衔接
- async 函数内有 await,但函数自身未声明 throws、也未包裹 try/catch
推荐使用 @typescript-eslint/no-floating-promises(TypeScript)或 no-promise-reject-errors + 自定义规则(JS)组合覆盖。
CI/CD 中可落地的三步配置
-
启用严格 ESLint 规则:在项目
.eslintrc.js中加入"@typescript-eslint/no-floating-promises": ["error", { "ignoreIIFE": true }]
该规则会标记所有未被await、Promise.then()、Promise.catch()或try/catch消费的 Promise 表达式,包括裸 await 后未接错误处理的场景。 -
在 CI 流水线中强制执行:Jenkins/GitLab CI/Actions 中添加检查步骤:
npm run lint -- --max-warnings 0--max-warnings 0确保任何警告(含 no-floating-promises 警告)都导致构建失败。 -
配合 TypeScript 的严格编译选项:开启
"strict": true和"noImplicitAny": true,并确保tsconfig.json中"skipLibCheck": false,让类型系统辅助识别未处理的异步路径(如函数返回Promise<void></void>却未 await)。
注意边界:哪些情况不应被拦截
强行一刀切会阻碍合理开发模式,以下属于正当用法,建议在规则中白名单豁免:
- 顶层 await(ES2022+,用于模块初始化,如配置加载)
- IIFE 包裹的 await(如
(async () => { await init(); })();) - 明确用于触发副作用且无需等待结果的调用(如
trackEvent().catch(() => {});)——应加空 catch 并注释说明 - 测试文件中为简化逻辑写的裸 await(可通过
/* eslint-disable */在 describe 块顶部临时关闭)
进阶:结合 SonarQube 做长期趋势管控
将 ESLint 结果导出为 eslint-report.json,接入 SonarQube,设置质量门禁:
“Critical issues from no-floating-promises must be zero”
这样不仅卡住提交,还能追踪团队改进趋势、识别高频出错模块,推动 API 封装层统一提供带默认错误兜底的 async 工具函数(如 safeFetch())。











