强类型错误透传需结构化携带语义、上下文、位置及影响范围;异常上下文信息采集器注入请求标识、节点元数据和业务快照,并按执行阶段打语义标签,固化trace_id、request_id等标准字段,错误响应严格遵循schema,extensions.context统一收纳上下文,客户端依语义标签策略化处理。

要让强类型错误在全链路追踪中真正“透传”,关键不是只把错误对象抛出去,而是把错误的语义、上下文、位置和影响范围一起结构化地带过去。异常上下文信息采集器就是干这个的——它不单捕获 error.message 和 stack,而是主动注入请求生命周期标识、执行节点元数据、业务上下文快照等可被下游服务识别和消费的信息。
明确错误语义边界,绑定执行链路节点
GraphQL 或微服务调用中,同一类错误(如“用户未找到”)在不同环节含义不同:入口校验失败是 CONTEXTUAL 级,数据库查询超时是 OPERATIONAL 级,字段解析失败则属于 SEMANTIC 级。采集器需根据当前执行阶段自动打上语义标签,例如:
- 网关层拦截 → 添加
"domain": "auth", "phase": "validation" - Resolver 执行中 → 注入
"field_path": "user.profile", "resolver_id": "userResolverV2" - 下游 HTTP 调用返回 404 → 补充
"upstream_service": "identity-svc", "http_status": 404
统一注入结构化上下文字段
避免各服务自定义字段导致日志/trace 解析混乱。采集器应在错误对象顶层固化一组标准字段,所有语言 SDK 保持一致:
- trace_id 和 span_id:从当前 OpenTelemetry 上下文提取,强制存在
- request_id:与网关或负载均衡生成的 ID 对齐,便于跨系统关联
-
context_snapshot:按采样率启用(如 PHP 8.9 的
error_context_snapshot = true),仅包含作用域内非敏感变量(如user_id,order_sn,tenant_code) -
severity:使用枚举值(如
"CRITICAL"/"ERROR"),而非字符串或数字码,支持监控系统直接按标签聚合
错误对象序列化时保留类型契约
强类型的核心在于响应结构稳定。即使发生异常,GraphQL 错误响应或 REST API 的 error body 仍需严格符合预定义 schema:
- 错误根字段固定为
errors: [{ message, locations, path, extensions }],其中extensions是唯一可扩展区域 - 所有上下文字段必须收口进
extensions.context,且其结构由接口契约提前约定(如必含trace_id、node、severity) - 禁止在
message中拼接堆栈或变量值;敏感信息脱敏后才允许进入extensions.debug_info(仅限 debug 模式)
客户端按语义标签做差异化处理
透传的价值最终体现在消费端。前端或下游服务应基于采集器注入的语义字段做策略路由:
- 收到
extensions.severity === "CRITICAL"→ 触发降级 UI,跳转兜底页 - 检测到
extensions.phase === "serialization"→ 不重试,直接报格式错误给用户 - 发现
extensions.upstream_service非空 → 自动将告警路由至对应服务 SRE 群,附带完整 trace_id - 结合
extensions.field_path动态高亮表单项或禁用相关操作按钮










