rsnext/examples/with-sentry/server.js
Václav Nosek 02966afd5a [with-sentry] example: Make 'utils/sentry.js' more flexible (#6769)
* Make `ctx` optional in `captureException` function

* Make 'release' optional when calling sentry util

* Fix code style
2019-03-27 13:23:34 +01:00

62 lines
1.8 KiB
JavaScript

const next = require('next')
const express = require('express')
const cookieParser = require('cookie-parser')
const uuidv4 = require('uuid/v4')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handler = app.getRequestHandler()
function sessionCookie (req, res, next) {
const htmlPage =
!req.path.match(/^\/(_next|static)/) &&
!req.path.match(/\.(js|map)$/) &&
req.accepts('text/html', 'text/css', 'image/png') === 'text/html'
if (!htmlPage) {
next()
return
}
if (!req.cookies.sid || req.cookies.sid.length === 0) {
req.cookies.sid = uuidv4()
res.cookie('sid', req.cookies.sid)
}
next()
}
const sourcemapsForSentryOnly = token => (req, res, next) => {
// In production we only want to serve source maps for sentry
if (!dev && !!token && req.headers['x-sentry-token'] !== token) {
res
.status(401)
.send('Authentication access token is required to access the source map.')
return
}
next()
}
app.prepare().then(() => {
// The app.buildId is only available after app.prepare(), hence why we setup
// here.
const { Sentry } = require('./utils/sentry')(app.buildId)
express()
// This attaches request information to sentry errors
.use(Sentry.Handlers.requestHandler())
.use(cookieParser())
.use(sessionCookie)
.get(/\.map$/, sourcemapsForSentryOnly(process.env.SENTRY_TOKEN))
// Regular next.js request handler
.use(handler)
// This handles errors if they are thrown before raching the app
.use(Sentry.Handlers.errorHandler())
.listen(port, err => {
if (err) {
throw err
}
// eslint-disable-next-line no-console
console.log(`> Ready on http://localhost:${port}`)
})
})