|
1 | | -import traceResolvers from '../src/traceResolvers'; |
2 | 1 | import { graphql } from 'graphql'; |
3 | | -import schema from './helpers/schema'; |
| 2 | +import { traceSchema } from './helpers/schema'; |
4 | 3 | import nock from 'nock'; |
5 | 4 | import anyTest, { ExecutionContext, TestInterface } from 'ava'; |
6 | 5 | import AWSXRay, { Segment, Subsegment } from 'aws-xray-sdk-core'; |
7 | 6 | import retryPromise from 'promise-retry'; |
| 7 | +import { ExecutionResult, ExecutionResultDataDefault } from 'graphql/execution/execute'; |
| 8 | +import { Mutation } from './__generated__/graphql'; |
8 | 9 |
|
9 | 10 | AWSXRay.capturePromise(); |
10 | 11 |
|
| 12 | +type GraphQlQuery = Parameters<typeof graphql>[1]; |
| 13 | +type Namespace = ReturnType<typeof AWSXRay.getNamespace>; |
| 14 | + |
11 | 15 | interface TestContext { |
| 16 | + ns: Namespace; |
12 | 17 | segment: Segment; |
13 | | - graphql: (query: string) => Promise<any>; |
| 18 | + graphql: <TData = ExecutionResultDataDefault>(query: GraphQlQuery) => Promise<ExecutionResult<TData>>; |
14 | 19 | } |
15 | 20 |
|
16 | 21 | const test = anyTest as TestInterface<TestContext>; |
17 | 22 |
|
18 | 23 | test.beforeEach(function (test) { |
| 24 | + const schema = traceSchema(); |
19 | 25 | nock.disableNetConnect(); |
20 | 26 | nock.enableNetConnect('127.0.0.1'); |
21 | 27 |
|
22 | | - const ns = AWSXRay.getNamespace(); |
23 | | - const segment = new AWSXRay.Segment('parent'); |
| 28 | + const ns: Namespace = AWSXRay.getNamespace(); |
| 29 | + test.context.ns = ns; |
24 | 30 |
|
| 31 | + const segment = new AWSXRay.Segment('parent'); |
25 | 32 | test.context.segment = segment; |
26 | | - traceResolvers(schema); |
27 | | - test.context.graphql = ns.bind(function (query: string) { |
| 33 | + |
| 34 | + test.context.graphql = ns.bind(function (query: GraphQlQuery) { |
28 | 35 | AWSXRay.setSegment(segment); |
29 | | - return graphql(schema, query); |
| 36 | + try { |
| 37 | + return graphql(schema, query); |
| 38 | + } finally { |
| 39 | + segment.close(); |
| 40 | + } |
30 | 41 | }); |
31 | 42 | }); |
32 | 43 |
|
@@ -84,11 +95,22 @@ test('Trace segments are reported as errors when resolver throws an error synchr |
84 | 95 | test.truthy(segment.subsegments![0].fault); |
85 | 96 | }); |
86 | 97 |
|
| 98 | +test('Trace segments are reported as errors when resolver throws an error asynchronously', async function (test) { |
| 99 | + const { segment, graphql } = test.context; |
| 100 | + await graphql('{ throwsAsynchronously }'); |
| 101 | + |
| 102 | + test.is(segment.subsegments?.length, 1); |
| 103 | + test.is(segment.subsegments![0].name, 'GraphQL throwsAsynchronously'); |
| 104 | + test.falsy(segment.subsegments![0].in_progress); |
| 105 | + // @ts-ignore |
| 106 | + test.truthy(segment.subsegments![0].fault); |
| 107 | +}); |
| 108 | + |
87 | 109 | async function testAsyncResolver (test: ExecutionContext<TestContext>, unblockQueryBuilder: (id: string) => string): Promise<Subsegment> { |
88 | 110 | const { segment, graphql } = test.context; |
89 | 111 |
|
90 | | - const createResult = await graphql('mutation { createBlocking }'); |
91 | | - const blockedId = createResult.data.createBlocking; |
| 112 | + const createResult = await graphql<Mutation>('mutation { createBlocking }'); |
| 113 | + const blockedId = createResult.data!.createBlocking; |
92 | 114 |
|
93 | 115 | test.is(segment.subsegments?.length, 1); |
94 | 116 | test.is(segment.subsegments![0].name, 'GraphQL createBlocking'); |
|
0 commit comments