-
Notifications
You must be signed in to change notification settings - Fork 619
fix: Enable union type support in @opentelemetry/instrumentation-graphql (#1506) #2923
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9f087c7
b174583
8a08afd
c7f51ad
2da8f10
0c5ef73
115cec5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -305,11 +305,7 @@ export function wrapFields( | |
| tracer: api.Tracer, | ||
| getConfig: () => GraphQLInstrumentationParsedConfig | ||
| ): void { | ||
| if ( | ||
| !type || | ||
| typeof type.getFields !== 'function' || | ||
| type[OTEL_PATCHED_SYMBOL] | ||
| ) { | ||
| if (!type || type[OTEL_PATCHED_SYMBOL]) { | ||
| return; | ||
| } | ||
| const fields = type.getFields(); | ||
|
|
@@ -328,16 +324,47 @@ export function wrapFields( | |
| } | ||
|
|
||
| if (field.type) { | ||
| let unwrappedType: any = field.type; | ||
|
|
||
| while (unwrappedType.ofType) { | ||
| unwrappedType = unwrappedType.ofType; | ||
| const unwrappedTypes = unwrapType(field.type); | ||
| for (const unwrappedType of unwrappedTypes) { | ||
| wrapFields(unwrappedType, tracer, getConfig); | ||
| } | ||
| wrapFields(unwrappedType, tracer, getConfig); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| function unwrapType( | ||
| type: graphqlTypes.GraphQLOutputType | ||
| ): readonly graphqlTypes.GraphQLObjectType[] { | ||
| // unwrap wrapping types (non-nullable and list types) | ||
| if ('ofType' in type) { | ||
| return unwrapType(type.ofType); | ||
| } | ||
|
|
||
| // unwrap union types | ||
| if (isGraphQLUnionType(type)) { | ||
| return type.getTypes(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I have a similar question. Are we certain that
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair concern. Doing a quick search through the graphql type definitions,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Doing a bit of research... From the Apollo Graphql Union and Interfaces schema help page
It sounds like unions strictly require their components to be objects and that nested union are not allowed. Though, to dispel any doubts, I tried launching my graphql server with a dummy union type that uses other union types:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for your thorough explanation @nitrofski :) |
||
| } | ||
|
|
||
| // return object types | ||
| if (isGraphQLObjectType(type)) { | ||
| return [type]; | ||
| } | ||
|
|
||
| return []; | ||
| } | ||
|
|
||
| function isGraphQLUnionType( | ||
| type: graphqlTypes.GraphQLType | ||
| ): type is graphqlTypes.GraphQLUnionType { | ||
| return 'getTypes' in type && typeof type.getTypes === 'function'; | ||
| } | ||
|
|
||
| function isGraphQLObjectType( | ||
| type: graphqlTypes.GraphQLType | ||
| ): type is graphqlTypes.GraphQLObjectType { | ||
| return 'getFields' in type && typeof type.getFields === 'function'; | ||
| } | ||
|
|
||
| const handleResolveSpanError = ( | ||
| resolveSpan: api.Span, | ||
| err: any, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar enough with this library. Are we certain that all possible values of
typehave a function namedgetFields?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is part of
graphqlTypes.GraphQLObjectType. As long as we maintain type safety and that the type definitions are accurate (to my testing, they were), we should be safe.The previous implementation used an
anytype before recursing, so they lost type safety and ended up passing non-compliant object. It had to re-assess the object here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay then