Created
February 7, 2017 08:09
-
-
Save nodkz/d7caf219dcb6e65b94900a9f549bf9d0 to your computer and use it in GitHub Desktop.
Sentry/raven manual config
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import path from 'path'; | |
import express from 'express'; | |
import { merge } from 'lodash'; | |
import graphqlHTTP from 'express-graphql'; | |
import PrettyError from 'pretty-error'; | |
import expressHttpProxy from 'express-http-proxy'; | |
import bodyParser from 'body-parser'; | |
import raven from 'raven'; | |
import morgan from 'morgan'; | |
import { PORT, PUBLIC_URL } from 'config'; | |
import GraphQLSchema from 'schema'; | |
import serverRenderHtml from './serverRenderHtml'; | |
import getAuthRouter from 'app/auth/server'; | |
import * as myJWT from 'app/auth/_jwt'; | |
const pe = new PrettyError(); | |
pe.skipNodeFiles(); | |
pe.skipPackage('express', 'graphql'); | |
raven.config(!__DEV__ && 'https://111:222@sentry.io/127680', { | |
release: __REVISION__, | |
tags: { git_commit: __GIT_COMMIT__ }, | |
environment: process.env.NODE_ENV, | |
captureUnhandledRejections: true, | |
}).install(); | |
const server = express(); | |
server.use((req, res, next) => { | |
req.ravenPipe = []; | |
req.ravenAddContext = (context) => { | |
req.ravenPipe.push(context); | |
}; | |
req.ravenGetContext = () => { | |
const context = { | |
user: { | |
id: req.cabinetId, | |
username: req.userEmail, | |
email: req.userEmail, | |
}, | |
tags: { | |
...(req.headers['x-referrer-url'] && { | |
referrer: req.headers['x-referrer-url'] | |
}), | |
...(req.admin && { | |
adminId: req.admin.id, | |
adminEmail: req.admin.email, | |
}) | |
} | |
}; | |
return merge(context, ...req.ravenPipe, raven.parsers.parseRequest(req)); | |
}; | |
next(); | |
}); | |
server.use(morgan(__DEV__ ? 'dev' : 'combined')); | |
server.get('/aws-health-check', (req, res) => { | |
res.send('Healthy!'); | |
}); | |
const graphQLMiddleware = graphqlHTTP(req => ({ | |
schema: GraphQLSchema, | |
graphiql: true, | |
formatError: (error) => { | |
req.ravenAddContext({ | |
extra: { | |
source: error.source && error.source.body, | |
positions: error.positions, | |
path: error.path, | |
}, | |
}); | |
if (error.path || error.name !== 'GraphQLError') { | |
req.ravenAddContext({ tags: { graphql: 'exec_error' } }); | |
raven.captureException(error, req.ravenGetContext()); | |
console.error(pe.render(error)); | |
} else { | |
req.ravenAddContext({ tags: { graphql: 'wrong_query' } }); | |
raven.captureMessage(`GraphQLWrongQuery: ${error.message}`, req.ravenGetContext()); | |
console.error(pe.render(error.message)); | |
} | |
return { | |
message: error.message, | |
stack: process.env.NODE_ENV === 'development' ? error.stack.split('\n') : null, | |
}; | |
} | |
})); | |
server.use('/graphql', | |
myJWT.validateRequest, | |
graphQLMiddleware | |
); | |
server.get('/*', async (req, res, next) => { | |
serverRenderHtml(req, res, next); | |
}); | |
// Error handling | |
server.use((err, req, res, next) => { | |
const status = err.status || err.statusCode || err.status_code || 500; | |
if (status < 500) return next(err); | |
res.sentry = raven.captureException(err, req.ravenGetContext()); | |
return next(err); | |
}); | |
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}/`); | |
}); |
only problem i can find here, formatError is triggered multiple times.
e.g. for each edges, which can end up being quite a bit.
I am thinking about adding in a requestId which should allow me to group them together, a tiny bit ? but not 100% sure how sentry handles multiple errors per request. Perhaps the best solution is just to trigger a sentry new event per error?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In the
req.ravenPipe
I put all contexts. And only when error occurs call fat ravenGetContext() function. So it is a quite performant solution.