不能在CI/CD中强行拦截await,因其是语法糖、编译后消失;须通过TypeScript编译检查、ESLint门禁(no-floating-promises设为error)、运行时unhandledRejection监听三层协同防控。

不能“强行拦截裸露 await”——这不是 CI/CD 的职责,也不是静态检查工具该做的事。真正要做的,是**在代码提交前就识别并阻断不安全的异步调用模式**,靠的是语言层约束 + 静态分析 + 流水线门禁协同,而非在 CI/CD 里对 await 做运行时拦截。
为什么不能靠 CI/CD “拦截 await”
await 是语法糖,编译后即消失;CI/CD 流水线面对的是已转译的 JavaScript/TypeScript 产物(如 ES2019+ 或 .js 文件),无法还原原始 await 位置。所谓“裸露 await”,本质是开发者未处理 Promise 拒绝(unhandled rejection)的风险行为,属于编码规范与错误处理契约问题,必须在源码阶段管控。
真正有效的三层防御配置
第一层:TypeScript 编译期强制捕获
启用严格异步检查,配合 ESLint 插件提前报错:
使用 Vite 8、React 19、Tailwind CSS v4、shadcn/ui、Biome、Vitest 和 Hono 构建全栈 TypeScript 应用,涵盖前端(Vite/Rolldown 构建 + 开发)...
- 在
tsconfig.json中开启:"noImplicitReturns": true、"strictNullChecks": true - 安装并配置
@typescript-eslint/eslint-plugin,启用规则:require-await(禁止无 await 的 async 函数)、no-floating-promises(禁止未被 await 或 .catch()/.then() 处理的 Promise) - 示例违规代码会立即报错:
async function fetchData() {<br> fetch('/api/user'); // ❌ no-floating-promises 触发
第二层:ESLint 流水线门禁卡点
在 CI/CD 的 test / lint 阶段加入强校验,失败即中断:
- GitLab CI 示例:
lint:ts:<br> stage: validate<br> script:<br> - npm ci<br> - npx eslint 'src/**/*.{ts,tsx}' --max-warnings 0 - GitHub Actions 中使用
eslint-action,配置fail-on-warnings: true - 关键:把
no-floating-promises设为"error"级别,不是 warning
第三层:运行时兜底与可观测性加固
即便静态检查通过,仍需防止漏网之鱼在运行时崩溃:
- 全局监听未捕获 Promise 拒绝:
process.on('unhandledRejection', (reason, promise) => {<br> console.error('Unhandled Rejection at:', promise, 'reason:', reason);<br> process.exit(1); // CI 环境中直接退出构建<br>}); - 在 Jest / Vitest 测试中启用
detectOpenHandles: true和forceExit: true,避免测试因悬空 Promise 卡住 - CI 日志中自动匹配关键词:
unhandledRejection、Unhandled promise rejection,命中即标记构建失败
不复杂但容易忽略:真正的“拦截”,发生在开发者敲下 fetch() 的那一刻——IDE 实时提示、pre-commit hook 强制校验、流水线 lint 阶段零容忍。CI/CD 不是补丁机,而是守门人。守住这道门,裸 await 就进不了主干。

















