Skip to content

Instantly share code, notes, and snippets.

@izumskee
Forked from nodkz/apolloServer2019.ts
Created February 6, 2018 15:11
Show Gist options
  • Save izumskee/04806a40effabf1c6eb3479b47fb82af to your computer and use it in GitHub Desktop.
Save izumskee/04806a40effabf1c6eb3479b47fb82af to your computer and use it in GitHub Desktop.
GraphQL error tracking with sentry.io
/* eslint-disable no-console, import/first */
import path from 'path';
import express from 'express';
import expressStaticGzip from 'express-static-gzip';
import graphqlHTTP from 'express-graphql';
import PrettyError from 'pretty-error';
import bodyParser from 'body-parser';
import raven from 'raven';
import morgan from 'morgan';
import { graphqlBatchHTTPWrapper } from 'react-relay-network-layer';
import { PORT, PUBLIC_URL } from 'config';
import GraphQLSchema from 'schema';
import * as myJWT from 'app/auth/_jwt';
import serverRenderHtml from './serverRenderHtml';
const pe = new PrettyError();
pe.skipNodeFiles();
pe.skipPackage('express', 'graphql');
raven.config(!__DEV__ && 'https://secret1:secret2@sentry.io/1234567', {
release: __REVISION__,
tags: { git_commit: __GIT_COMMIT__ },
environment: process.env.NODE_ENV,
}).install();
const server = express();
server.use(raven.requestHandler());
server.use(morgan(__DEV__ ? 'dev' : 'combined'));
const graphQLMiddleware = graphqlHTTP(req => ({
schema: GraphQLSchema,
graphiql: true,
formatError: (error) => {
if (error.path || error.name !== 'GraphQLError') {
console.error(pe.render(error));
raven.captureException(error,
raven.parsers.parseRequest(req, {
tags: { graphql: 'exec_error' },
extra: {
source: error.source && error.source.body,
positions: error.positions,
path: error.path,
},
})
);
} else {
console.error(pe.render(error.message));
raven.captureMessage(`GraphQLWrongQuery: ${error.message}`,
raven.parsers.parseRequest(req, {
tags: { graphql: 'wrong_query' },
extra: {
source: error.source && error.source.body,
positions: error.positions,
},
})
);
}
return {
message: error.message,
stack: process.env.NODE_ENV === 'development' ? error.stack.split('\n') : null,
};
},
context: {
userId: req.userId,
userEmail: req.userEmail,
admin: req.admin,
getUserPromise: req.getUserPromise ? req.getUserPromise.bind(req) : null,
getAdminPromise: req.getAdminPromise ? req.getAdminPromise.bind(req) : null,
ip: req.ip || (req.connection || {}).remoteAddress,
},
}));
server.use('/graphql/batch',
myJWT.validateRequest,
bodyParser.json(),
graphqlBatchHTTPWrapper(graphQLMiddleware)
);
server.use('/graphql',
myJWT.validateRequest,
graphQLMiddleware
);
server.use(expressStaticGzip(path.join(__dirname, 'public')));
server.get('/*', serverServeApp);
// Error handling
server.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
console.log(pe.render(err)); // eslint-disable-line no-console
res.status(err.status || 500);
res.setHeader('Content-Type', 'text/plain');
res.send(__DEV__ ? err.stack : 'Oops, internal server error');
});
server.listen(PORT, () => {
console.log(`The server is running at http://localhost:${PORT}/`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment