diff --git a/packages/apollo-engine-reporting/src/extension.ts b/packages/apollo-engine-reporting/src/extension.ts index 8525a2234ec..cfa4bccb051 100644 --- a/packages/apollo-engine-reporting/src/extension.ts +++ b/packages/apollo-engine-reporting/src/extension.ts @@ -5,6 +5,7 @@ import { responsePathAsArray, ResponsePath, DocumentNode, + ExecutionArgs, GraphQLError, } from 'graphql'; import { @@ -237,13 +238,21 @@ export class EngineReportingExtension }; } - public didResolveOperation(o: { - requestContext: GraphQLRequestContext; - }) { - const { requestContext } = o; - - this.operationName = requestContext.operationName; - this.documentAST = requestContext.document; + public executionDidStart(o: { executionArgs: ExecutionArgs }) { + // If the operationName is explicitly provided, save it. If there's just one + // named operation, the client doesn't have to provide it, but we still want + // to know the operation name so that the server can identify the query by + // it without having to parse a signature. + // + // Fortunately, in the non-error case, we can just pull this out of + // the first call to willResolveField's `info` argument. In an + // error case (eg, the operationName isn't found, or there are more + // than one operation and no specified operationName) it's OK to continue + // to file this trace under the empty operationName. + if (o.executionArgs.operationName) { + this.operationName = o.executionArgs.operationName; + } + this.documentAST = o.executionArgs.document; } public willResolveField( @@ -252,6 +261,11 @@ export class EngineReportingExtension _context: TContext, info: GraphQLResolveInfo, ): ((error: Error | null, result: any) => void) | void { + if (this.operationName === undefined) { + this.operationName = + (info.operation.name && info.operation.name.value) || ''; + } + const path = info.path; const node = this.newNode(path); node.type = info.returnType.toString();