GraphQL @Mutation与自定义Log装饰器顺序异常及方法日志方案咨询
优先排查内容
- 自定义装饰器是否丢失原方法元数据
TS/JS的方法装饰器执行顺序为从下往上(离方法越近的装饰器越先执行),你原来的写法@Mutation()在上、@Log()在下,执行顺序为先执行@Log()替换方法实现,再执行@Mutation()给替换后的方法挂载GraphQL所需的返回类型、参数定义、Resolver标识等元数据,因此可以正常运行。调换顺序后会先执行@Mutation()给原方法挂载元数据,再执行@Log()将方法替换为新的匿名函数,新函数没有继承原方法的元数据,GraphQL读取不到所需配置就会报错。 - 装饰器内返回值处理是否正确
你当前写的@Log()装饰器里调用原方法时没有加await,打印的result实际是Promise对象而非真实返回值,虽然不是直接报错原因,但属于功能缺陷。 - 装饰器返回的descriptor属性是否正确
确认你没有修改descriptor的writable、enumerable等默认属性,避免影响其他装饰器的正常读取。
可行解决方案
方案1:修复自定义Log装饰器
补充元数据复制逻辑,保证原方法挂载的所有元数据都能继承到替换后的新方法上,修复后无论装饰器顺序如何都能正常运行:
import { copyMetadata } from '@nestjs/common/utils/copy-metadata.util'; export const Log = (): MethodDecorator => (target: Object, propertyKey: string, descriptor: PropertyDescriptor) => { const originalMethod = descriptor.value; const newMethod = async function (...args) { console.log('输入参数:', args); // 增加await获取真实返回结果 const result = await originalMethod.apply(this, args); console.log('输出结果:', result); return result; }; // 复制原方法的所有元数据到新方法 copyMetadata(originalMethod, newMethod); descriptor.value = newMethod; return descriptor; };
方案2:使用NestJS拦截器实现日志采集(更推荐)
无需给每个方法加装饰器,无侵入性,不会和现有GraphQL装饰器产生冲突:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, UseInterceptors } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; import { GqlExecutionContext } from '@nestjs/graphql'; @Injectable() export class GraphqlLoggerInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const gqlCtx = GqlExecutionContext.create(context); const resolverName = gqlCtx.getHandler().name; const inputArgs = gqlCtx.getArgs(); console.log(`[Resolver: ${resolverName}] 输入参数:`, inputArgs); return next.handle().pipe( tap(res => console.log(`[Resolver: ${resolverName}] 输出结果:`, res)) ); } }
使用时可以全局注册,或者给单个Resolver/方法加@UseInterceptors(GraphqlLoggerInterceptor)即可。
方案3:使用Apollo GraphQL插件
直接利用Apollo Server的生命周期钩子做全局日志采集,完全不侵入业务代码,适合需要统一采集所有GraphQL请求日志的场景。
内容的提问来源于stack exchange,提问作者gentlejo
相关产品推荐
相关产品推荐

