mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Merge branch 'master' into canary
# Conflicts: # lerna.json # packages/next-server/package.json # packages/next/package.json
This commit is contained in:
commit
4fea345f5d
23
examples/with-sentry/next.config.js
Normal file
23
examples/with-sentry/next.config.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
const webpack = require('webpack')
|
||||
const nextSourceMaps = require('@zeit/next-source-maps')()
|
||||
|
||||
const SENTRY_DSN = ''
|
||||
|
||||
module.exports = nextSourceMaps({
|
||||
webpack: (config, { dev, isServer, buildId }) => {
|
||||
if (!dev) {
|
||||
config.plugins.push(
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.SENTRY_DSN': JSON.stringify(SENTRY_DSN),
|
||||
'process.env.SENTRY_RELEASE': JSON.stringify(buildId)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (!isServer) {
|
||||
config.resolve.alias['@sentry/node'] = '@sentry/browser'
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
})
|
|
@ -1,23 +1,48 @@
|
|||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
|
||||
class Index extends React.Component {
|
||||
static getInitialProps ({ query, req }) {
|
||||
if (query.raiseError) {
|
||||
throw new Error('Error in getInitialProps')
|
||||
}
|
||||
}
|
||||
|
||||
state = {
|
||||
raiseError: false
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
if (this.state.raiseError) {
|
||||
throw new Error('Houston, we have a problem')
|
||||
if (this.state.raiseErrorInUpdate) {
|
||||
throw new Error('Error in componentDidUpdate')
|
||||
}
|
||||
}
|
||||
|
||||
raiseError = () => this.setState({ raiseError: true })
|
||||
raiseErrorInUpdate = () => this.setState({ raiseErrorInUpdate: '1' })
|
||||
raiseErrorInRender = () => this.setState({ raiseErrorInRender: '1' })
|
||||
|
||||
render () {
|
||||
if (this.state.raiseErrorInRender) {
|
||||
throw new Error('Error in render')
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Index page</h2>
|
||||
<button onClick={this.raiseError}>Click to raise the error</button>
|
||||
<ul>
|
||||
<li><a href='#' onClick={this.raiseErrorInRender}>Raise the error in render</a></li>
|
||||
<li><a href='#' onClick={this.raiseErrorInUpdate}>Raise the error in componentDidUpdate</a></li>
|
||||
<li>
|
||||
<Link href={{ pathname: '/', query: { raiseError: '1' } }}>
|
||||
<a>Raise error in getInitialProps of client-loaded page</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href='/?raiseError=1'>
|
||||
Raise error in getInitialProps of server-loaded page
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
66
examples/with-sentry/server.js
Normal file
66
examples/with-sentry/server.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
const next = require('next')
|
||||
const express = require('express')
|
||||
const cookieParser = require('cookie-parser')
|
||||
const Sentry = require('@sentry/node')
|
||||
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 handle = app.getRequestHandler()
|
||||
|
||||
require('./utils/sentry')
|
||||
|
||||
app.prepare()
|
||||
.then(() => {
|
||||
const server = express()
|
||||
|
||||
// This attaches request information to sentry errors
|
||||
server.use(Sentry.Handlers.requestHandler())
|
||||
|
||||
server.use(cookieParser())
|
||||
|
||||
server.use((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()
|
||||
})
|
||||
|
||||
// In production we don't want to serve sourcemaps for anyone
|
||||
if (!dev) {
|
||||
const hasSentryToken = !!process.env.SENTRY_TOKEN
|
||||
server.get(/\.map$/, (req, res, next) => {
|
||||
if (hasSentryToken && req.headers['x-sentry-token'] !== process.env.SENTRY_TOKEN) {
|
||||
res
|
||||
.status(401)
|
||||
.send(
|
||||
'Authentication access token is required to access the source map.'
|
||||
)
|
||||
return
|
||||
}
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
server.get('*', (req, res) => handle(req, res))
|
||||
|
||||
// This handles errors if they are thrown before raching the app
|
||||
server.use(Sentry.Handlers.errorHandler())
|
||||
|
||||
server.listen(port, err => {
|
||||
if (err) throw err
|
||||
console.log(`> Ready on http://localhost:${port}`)
|
||||
})
|
||||
})
|
63
examples/with-sentry/utils/sentry.js
Normal file
63
examples/with-sentry/utils/sentry.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
const Sentry = require('@sentry/node')
|
||||
const Cookie = require('js-cookie')
|
||||
|
||||
if (process.env.SENTRY_DSN) {
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN,
|
||||
release: process.env.SENTRY_RELEASE,
|
||||
maxBreadcrumbs: 50,
|
||||
attachStacktrace: true
|
||||
})
|
||||
}
|
||||
|
||||
function captureException (err, { req, res, errorInfo, query, pathname }) {
|
||||
Sentry.configureScope(scope => {
|
||||
if (err.message) {
|
||||
// De-duplication currently doesn't work correctly for SSR / browser errors
|
||||
// so we force deduplication by error message if it is present
|
||||
scope.setFingerprint([err.message])
|
||||
}
|
||||
|
||||
if (err.statusCode) {
|
||||
scope.setExtra('statusCode', err.statusCode)
|
||||
}
|
||||
|
||||
if (res && res.statusCode) {
|
||||
scope.setExtra('statusCode', res.statusCode)
|
||||
}
|
||||
|
||||
if (process.browser) {
|
||||
scope.setTag('ssr', false)
|
||||
scope.setExtra('query', query)
|
||||
scope.setExtra('pathname', pathname)
|
||||
|
||||
// On client-side we use js-cookie package to fetch it
|
||||
const sessionId = Cookie.get('sid')
|
||||
if (sessionId) {
|
||||
scope.setUser({ id: sessionId })
|
||||
}
|
||||
} else {
|
||||
scope.setTag('ssr', true)
|
||||
scope.setExtra('url', req.url)
|
||||
scope.setExtra('method', req.method)
|
||||
scope.setExtra('headers', req.headers)
|
||||
scope.setExtra('params', req.params)
|
||||
scope.setExtra('query', req.query)
|
||||
|
||||
// On server-side we take session cookie directly from request
|
||||
if (req.cookies.sid) {
|
||||
scope.setUser({ id: req.cookies.sid })
|
||||
}
|
||||
}
|
||||
|
||||
if (errorInfo) {
|
||||
scope.setExtra('componentStack', errorInfo.componentStack)
|
||||
}
|
||||
})
|
||||
|
||||
Sentry.captureException(err)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
captureException
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
@import "./button.css";
|
||||
|
||||
@tailwind preflight;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.hero {
|
||||
|
|
|
@ -10,9 +10,12 @@
|
|||
},
|
||||
"publish": {
|
||||
"npmClient": "npm",
|
||||
"allowBranch": "canary",
|
||||
"allowBranch": [
|
||||
"master",
|
||||
"canary"
|
||||
],
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
}
|
||||
},
|
||||
"version": "8.0.0-canary.24"
|
||||
"version": "8.0.0"
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"typescript": "lerna run typescript",
|
||||
"prepublish": "lerna run prepublish",
|
||||
"publish-canary": "lerna version prerelease --preid canary --force-publish && release --pre",
|
||||
"publish-stable": "lerna version --force-publish",
|
||||
"lint-staged": "lint-staged"
|
||||
},
|
||||
"pre-commit": "lint-staged",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "next-server",
|
||||
"version": "8.0.0-canary.24",
|
||||
"version": "8.0.0",
|
||||
"main": "./index.js",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "next",
|
||||
"version": "8.0.0-canary.24",
|
||||
"version": "8.0.0",
|
||||
"description": "The React Framework",
|
||||
"main": "./dist/server/next.js",
|
||||
"license": "MIT",
|
||||
|
@ -72,7 +72,7 @@
|
|||
"loader-utils": "1.1.0",
|
||||
"mkdirp-then": "1.2.0",
|
||||
"nanoid": "1.2.1",
|
||||
"next-server": "8.0.0-canary.24",
|
||||
"next-server": "8.0.0",
|
||||
"prop-types": "15.6.2",
|
||||
"prop-types-exact": "1.2.0",
|
||||
"react-error-overlay": "4.0.0",
|
||||
|
|
Loading…
Reference in a new issue