章节摘要:本章离开进出两半程,看层与层之间的"胶水"——async/await 的传播规则、请求上下文如何跨越异步边界、全局错误事件怎么接日志、进程级异常与优雅退出怎么兜。这些语义决定服务在异常路径上的可靠性。
本章主线从一封工单开始:某接口偶发 502,日志却一片干净——没有异常、没有慢查询记录,仿佛什么都没发生。排查这条线索要动用本章的全部知识:先确认异常有没有真的沿 Promise 链冒上来(6.1 的 await 语义与传播规则),再确认请求级上下文(请求 ID、用户)在异步边界上有没有断掉(6.1 的异步上下文方案),然后给全局错误事件接上结构化日志让"看不见的异常"显形(6.2),最后查到根因是一个未 await 的 Promise 静默 rejection——顺带补齐进程级兜底与优雅退出(6.3)。工单是虚构的,排查路径是真实的:这四站就是 Koa 异步可靠性知识的主干。
本章拐点在 6.1 的一个反直觉事实:Koa 里写错异步,最常见的症状不是报错,而是"安静"——漏了 await 的 Promise 在链外默默 rejection,响应照常出去,日志毫无动静。多数人的直觉是"错了总会报错吧",事实证明恰恰相反。由此得出本章结论:异步可靠性不靠自觉靠结构——所有异步留在链上(await 纪律)、断链的兜底放在进程级(rejection 事件)、异常的痕迹靠结构化日志(requestId 贯穿),三件套齐了,"偶发 502 但日志干净"这类幽灵问题才有抓手。
四站的知识依赖如下图。

这一章的知识在排查现场怎么用?给一个顺序清单。第一步,复现并分类:稳定复现的多半是逻辑错误(断 await、吞异常),偶发的先怀疑时序与并发——这时直接翻到 6.1 的三种漏 await 事故形态对号。第二步,按 reqId 拉链路:用 6.2 的结构化日志把同一次请求的所有痕迹拉到一起,看异常在哪一层最后留下记录。第三步,分层验证:临时在可疑层的进层与出层各加一条 debug 日志,观察它进没进、出没出——出层日志缺失就是截停或断链的铁证。第四步,进程级收网:如果日志全程干净但故障仍在,开 6.3 的 unhandledRejection 记录跑一段时间,链外的 rejection 会自己现形。这四步覆盖了异步类故障九成以上的排查路径。
服务自身的语义立稳了,下一章给洋葱套上防护层:常见的 Web 攻击面、安全响应头与 CSRF 对策、JWT 鉴权中间件的完整实现、HTTPS 与输入验证——安全不是功能,是层。