/
server.ts
88 lines (84 loc) · 3 KB
/
server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { existsSync, readFileSync } from 'fs';
import gql from 'graphql-tag';
import { buildSubgraphSchema } from '@apollo/subgraph';
import { ApolloServer } from '@apollo/server';
import {
addSyntheticsToSchema,
resolvers as fieldSyntheticsResolvers,
} from '@shared/field-synthetics';
import { resolvers } from '../resolvers';
import { ContextValue } from '../types/ContextValue';
import logger from '../logger';
import * as Sentry from '@sentry/node';
import { resolve } from 'path';
import responseCachePlugin from '@apollo/server-plugin-response-cache';
const schemaPath = existsSync('schema.graphql')
? 'schema.graphql'
: resolve('subgraphs', 'spotify', 'schema.graphql');
const typeDefs = gql(
readFileSync(schemaPath, {
encoding: 'utf-8',
})
);
const schema = buildSubgraphSchema({
typeDefs,
resolvers: {
...fieldSyntheticsResolvers,
...resolvers,
},
});
export const server = new ApolloServer<ContextValue>({
schema: addSyntheticsToSchema(schema),
introspection: true,
logger,
plugins: [
responseCachePlugin(),
{
async requestDidStart() {
return {
async didEncounterErrors(ctx) {
for (const err of ctx.errors) {
if (err.extensions?.code == 'GRAPHQL_VALIDATION_FAILED')
Sentry.withScope((scope) => {
// Annotate whether failing operation was query/mutation/subscription
scope.setTag('message', err.message);
// Log query and variables as extras
// (make sure to strip out sensitive data!)
scope.setExtra('query', ctx.request.query);
scope.setExtra('variables', ctx.request.variables);
if (err.path) {
// We can also add the path as breadcrumb
scope.addBreadcrumb({
category: 'query-path',
message: err.path.join(' > '),
level: 'debug',
});
}
Sentry.captureException(err);
});
else if (!ctx.operation) return;
else
Sentry.withScope((scope) => {
// Annotate whether failing operation was query/mutation/subscription
scope.setTag('kind', ctx.operation?.operation);
// Log query and variables as extras
// (make sure to strip out sensitive data!)
scope.setExtra('query', ctx.request.query);
scope.setExtra('variables', ctx.request.variables);
if (err.path) {
// We can also add the path as breadcrumb
scope.addBreadcrumb({
category: 'query-path',
message: err.path.join(' > '),
level: 'debug',
});
}
Sentry.captureException(err);
});
}
},
};
},
},
],
});