
graphql yoga 本身不提供与 apollo server 的 didencountererror 完全同名的钩子,但可通过内置的 uselogger 插件在请求生命周期中监听错误事件,并安全获取操作名、错误详情及(关键)上下文对象。
graphql yoga 本身不提供与 apollo server 的 didencountererror 完全同名的钩子,但可通过内置的 uselogger 插件在请求生命周期中监听错误事件,并安全获取操作名、错误详情及(关键)上下文对象。
在从 Apollo Server 迁移至 GraphQL Yoga 的过程中,开发者常关注错误处理钩子的等效替代方案。Apollo Server 的 didEncounterErrors 允许你在响应返回前访问 context 和 errors,便于日志记录、监控或上下文感知的错误归因。GraphQL Yoga 虽未直接暴露同名生命周期函数,但其官方插件系统提供了更语义化、更安全的替代方案:useLogger。
该插件专为结构化日志与错误观测设计,支持监听包括 "execute"、"parse"、"validate" 等多个事件;其中 "execute" 事件在执行阶段出错时触发,其 args 参数包含完整的 result(含 errors 数组)、operationName、variables,更重要的是——它完整保留了当前请求的 context 对象(前提是你的 Yoga 实例已正确配置 context 函数)。
以下是推荐的实现方式:
import { createYoga, useLogger } from 'graphql-yoga';
const yoga = createYoga({
schema,
plugins: [
useLogger({
logFn: (eventName, args) => {
// 仅在执行阶段发生错误时处理
if (eventName === 'execute' && args.result?.errors?.length > 0) {
const { operationName, result, context } = args;
// ✅ 此处可安全访问 context(如用户身份、请求ID、数据库连接等)
console.log('[GraphQL Error]', {
operationName,
errors: result.errors.map(e => e.message),
userId: context?.user?.id, // 示例:提取上下文中的用户信息
requestId: context?.requestId,
});
// 可扩展:上报 Sentry、写入日志服务、触发告警等
}
},
}),
],
});⚠️ 注意事项:
- useLogger 是 Yoga v4+ 的标准插件,确保你使用的是 graphql-yoga@^4.0.0 或更高版本;
- context 的可用性依赖于你在 createYoga() 配置中正确实现了 context 选项(例如 context: ({ request }) => ({ requestId: crypto.randomUUID(), user: await auth(request) }));
- 不要混淆 logFn 的 args 类型:args.context 即请求上下文,而 args.result.errors 是 GraphQL 执行层抛出的标准化错误数组(符合 GraphQL Spec Errors);
- 若需拦截并修改错误(如脱敏、添加 code 字段),应结合 useSchema 或自定义 formatError 函数,而非仅依赖 useLogger(后者仅用于观测,不可修改响应)。
总结:useLogger 不仅是 didEncounterError 的功能平替,更是 Yoga 推崇的“可观测优先”设计理念的体现——它将错误捕获与上下文关联解耦为声明式插件,兼顾灵活性与类型安全。迁移时只需替换插件逻辑,无需重构上下文注入机制,即可无缝实现增强型错误诊断能力。










