Skip to content

Commit 5d863bf

Browse files
committed
Merge branch 'main' into LukasHirt-feat/migrate-to-sentry-7
* main: fix(tracing): autoSessionTracking not working on the server-side (#466) fix: incorrect option name in the warning message (#467) chore(deps): don't update node version chore(deps): enable lock file maintenance for docs chore(docs): add .nvmrc for netlify and local dev chore(docs): update all sub-dependencies chore(docs): always build fix(deps): update devdependency @sentry/webpack-plugin to ^1.20.0 (#451) chore(deps): update all non-major dependencies (#449) chore(docs): fix documentation deploying, maybe
2 parents dd1cf8c + 67851ba commit 5d863bf

File tree

11 files changed

+2707
-2679
lines changed

11 files changed

+2707
-2679
lines changed

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
16

docs/yarn.lock

Lines changed: 1945 additions & 1826 deletions
Large diffs are not rendered by default.

lib/core/hooks.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,11 @@ export async function webpackConfigHook (moduleContainer, webpackConfigs, option
133133
*
134134
* @param {ThisParameterType<import('@nuxt/types').Module>} moduleContainer
135135
* @param {import('../../types/sentry').ResolvedModuleConfiguration} moduleOptions
136+
* @param {import('../../types/sentry').SentryHandlerProxy} sentryHandlerProxy
136137
* @param {import('consola').Consola} logger
137138
* @return {Promise<void>}
138139
*/
139-
export async function initializeServerSentry (moduleContainer, moduleOptions, logger) {
140+
export async function initializeServerSentry (moduleContainer, moduleOptions, sentryHandlerProxy, logger) {
140141
if (process.sentry) {
141142
return
142143
}
@@ -154,6 +155,8 @@ export async function initializeServerSentry (moduleContainer, moduleOptions, lo
154155

155156
if (canInitialize(moduleOptions)) {
156157
Sentry.init(config)
158+
sentryHandlerProxy.errorHandler = Sentry.Handlers.errorHandler()
159+
sentryHandlerProxy.requestHandler = Sentry.Handlers.requestHandler(moduleOptions.requestHandlerConfig)
157160
}
158161

159162
process.sentry = Sentry

lib/core/options.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export async function resolveClientOptions (moduleContainer, moduleOptions, logg
139139
if (typeof (options.customClientIntegrations) === 'string') {
140140
customClientIntegrations = moduleContainer.nuxt.resolver.resolveAlias(options.customClientIntegrations)
141141
} else {
142-
logger.warn(`Invalid customServerIntegrations option. Expected a file path, got "${typeof (options.customClientIntegrations)}".`)
142+
logger.warn(`Invalid customClientIntegrations option. Expected a file path, got "${typeof (options.customClientIntegrations)}".`)
143143
}
144144
}
145145

lib/core/utils.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,17 @@ export const clientSentryEnabled = options => !options.disabled && !options.disa
3737
* @return {boolean} True if node Sentry is enabled.
3838
*/
3939
export const serverSentryEnabled = options => !options.disabled && !options.disableServerSide
40+
41+
/**
42+
* @param {(...args: any[]) => any} fn
43+
* @return {(...args: any[]) => any}
44+
*/
45+
export function callOnce (fn) {
46+
let called = false
47+
return function callOnceWrapper () {
48+
if (!called) {
49+
called = true
50+
return fn(arguments)
51+
}
52+
}
53+
}

lib/module.js

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import consola from 'consola'
22
import merge from 'lodash.mergewith'
3-
import { Handlers as SentryHandlers, captureException, withScope } from '@sentry/node'
3+
import { captureException, withScope } from '@sentry/node'
44
import { buildHook, initializeServerSentry, shutdownServerSentry, webpackConfigHook } from './core/hooks'
5-
import { boolToText, canInitialize, clientSentryEnabled, envToBool, serverSentryEnabled } from './core/utils'
5+
import { boolToText, callOnce, canInitialize, clientSentryEnabled, envToBool, serverSentryEnabled } from './core/utils'
66

77
const logger = consola.withScope('nuxt:sentry')
88

@@ -72,21 +72,6 @@ export default function SentryModule (moduleOptions) {
7272
options.publishRelease = merged
7373
}
7474

75-
if (serverSentryEnabled(options)) {
76-
// @ts-ignore
77-
this.nuxt.hook('render:setupMiddleware', app => app.use(SentryHandlers.requestHandler(options.requestHandlerConfig)))
78-
// @ts-ignore
79-
this.nuxt.hook('render:errorMiddleware', app => app.use(SentryHandlers.errorHandler()))
80-
// @ts-ignore
81-
this.nuxt.hook('generate:routeFailed', ({ route, errors }) => {
82-
// @ts-ignore
83-
errors.forEach(({ error }) => withScope((scope) => {
84-
scope.setExtra('route', route)
85-
captureException(error)
86-
}))
87-
})
88-
}
89-
9075
if (canInitialize(options) && (clientSentryEnabled(options) || serverSentryEnabled(options))) {
9176
const status = `(client side: ${boolToText(clientSentryEnabled(options))}, server side: ${boolToText(serverSentryEnabled(options))})`
9277
logger.success(`Sentry reporting is enabled ${status}`)
@@ -104,21 +89,45 @@ export default function SentryModule (moduleOptions) {
10489
logger.info(`Sentry reporting is disabled (${why})`)
10590
}
10691

107-
this.nuxt.hook('build:before', () => buildHook(this, options, logger))
92+
this.nuxt.hook('build:before', callOnce(() => buildHook(this, options, logger)))
10893

109-
// This is messy but Nuxt provides many modes that it can be started with like:
110-
// - nuxt dev
111-
// - nuxt build
112-
// - nuxt start
113-
// - nuxt generate
114-
// but it doesn't really provide great way to differentiate those or enough hooks to
115-
// pick from. This should ensure that server Sentry will only be initialized **after**
116-
// the release version has been determined and the options template created but before
117-
// the build is started (if building).
118-
const initHook = this.options._build ? 'build:compile' : 'ready'
11994
if (serverSentryEnabled(options)) {
120-
this.nuxt.hook(initHook, () => initializeServerSentry(this, options, logger))
121-
this.nuxt.hook('generate:done', () => shutdownServerSentry())
95+
/**
96+
* Proxy that provides a dummy request handler before Sentry is initialized and gets replaced with Sentry's own
97+
* handler after initialization. Otherwise server-side request tracing would not work as it depends on Sentry being
98+
* initialized already during handler creation.
99+
* @type {import('../types/sentry').SentryHandlerProxy}
100+
*/
101+
const sentryHandlerProxy = {
102+
errorHandler: (error, req, res, next) => { next(error) },
103+
requestHandler: (req, res, next) => { next() },
104+
}
105+
// @ts-ignore
106+
this.nuxt.hook('render:setupMiddleware', app => app.use((req, res, next) => { sentryHandlerProxy.requestHandler(req, res, next) }))
107+
// @ts-ignore
108+
this.nuxt.hook('render:errorMiddleware', app => app.use((error, req, res, next) => { sentryHandlerProxy.errorHandler(error, req, res, next) }))
109+
// @ts-ignore
110+
this.nuxt.hook('generate:routeFailed', ({ route, errors }) => {
111+
// @ts-ignore
112+
errors.forEach(({ error }) => withScope((scope) => {
113+
scope.setExtra('route', route)
114+
captureException(error)
115+
}))
116+
})
117+
// This is messy but Nuxt provides many modes that it can be started with like:
118+
// - nuxt dev
119+
// - nuxt build
120+
// - nuxt start
121+
// - nuxt generate
122+
// but it doesn't really provide great way to differentiate those or enough hooks to
123+
// pick from. This should ensure that server Sentry will only be initialized **after**
124+
// the release version has been determined and the options template created but before
125+
// the build is started (if building).
126+
const initHook = this.options._build ? 'build:compile' : 'ready'
127+
this.nuxt.hook(initHook, callOnce(() => initializeServerSentry(this, options, sentryHandlerProxy, logger)))
128+
const shutdownServerSentryOnce = callOnce(() => shutdownServerSentry())
129+
this.nuxt.hook('generate:done', shutdownServerSentryOnce)
130+
this.nuxt.hook('close', shutdownServerSentryOnce)
122131
}
123132

124133
// Enable publishing of sourcemaps

netlify.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# https://docs.netlify.com/configure-builds/file-based-configuration
2+
3+
[build]
4+
base = "docs"
5+
command = "yarn generate"
6+
publish = "dist"

package.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,30 +57,30 @@
5757
"lodash.mergewith": "^4.6.2"
5858
},
5959
"devDependencies": {
60-
"@babel/core": "^7.19.3",
61-
"@babel/preset-env": "^7.19.3",
60+
"@babel/core": "^7.20.5",
61+
"@babel/preset-env": "^7.20.2",
6262
"@nuxt/types": "^2.15.8",
6363
"@nuxtjs/eslint-config-typescript": "^11.0.0",
6464
"@nuxtjs/module-test-utils": "^1.6.3",
65-
"@release-it/conventional-changelog": "^5.1.0",
65+
"@release-it/conventional-changelog": "^5.1.1",
6666
"@sentry/tracing": "^7.23.0",
67-
"@sentry/webpack-plugin": "^1.19.0",
68-
"@types/jest": "^29.0.3",
67+
"@sentry/webpack-plugin": "^1.20.0",
68+
"@types/jest": "^29.2.4",
6969
"@types/lodash.mergewith": "^4.6.7",
70-
"@types/node": "^14.18.31",
70+
"@types/node": "^16.18.8",
7171
"@types/request-promise-native": "^1.0.18",
7272
"babel-core": "^7.0.0-bridge.0",
7373
"babel-eslint": "^10.1.0",
74-
"babel-jest": "^29.1.0",
74+
"babel-jest": "^29.3.1",
7575
"codecov": "^3.8.3",
76-
"eslint": "^8.24.0",
77-
"eslint-plugin-jest": "^27.0.4",
78-
"jest": "^29.1.1",
76+
"eslint": "^8.29.0",
77+
"eslint-plugin-jest": "^27.1.6",
78+
"jest": "^29.3.1",
7979
"nuxt": "^2.15.8",
80-
"playwright-chromium": "^1.26.1",
81-
"release-it": "^15.4.2",
82-
"sentry-testkit": "^4.0.3",
83-
"typescript": "^4.8.4",
80+
"playwright-chromium": "^1.28.1",
81+
"release-it": "^15.5.1",
82+
"sentry-testkit": "^4.1.0",
83+
"typescript": "4.8.4",
8484
"vue": "2.7.14"
8585
}
8686
}

renovate.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
"commitMessageTopic": "{{prettyDepType}} {{depName}}"
1313
},
1414
"packageRules": [
15+
{
16+
"matchPackageNames": [
17+
"node"
18+
],
19+
"enabled": false
20+
},
1521
{
1622
"groupName": "Sentry Dependencies",
1723
"matchPackagePatterns": ["^@sentry"],
@@ -44,7 +50,13 @@
4450
"matchUpdateTypes": [
4551
"minor",
4652
"patch"
47-
]
53+
],
54+
"lockFileMaintenance": {
55+
"enabled": true,
56+
"extends": [
57+
"schedule:weekly"
58+
]
59+
}
4860
}
4961
]
5062
}

types/sentry.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import { IncomingMessage, ServerResponse } from 'http'
13
import { Options as WebpackOptions } from 'webpack'
24
import { Options as SentryOptions } from '@sentry/types'
35
import type { Options as SentryVueOptions } from '@sentry/vue/types/types'
46
import { SentryCliPluginOptions } from '@sentry/webpack-plugin'
57
import { Handlers } from '@sentry/node'
68

9+
export interface SentryHandlerProxy {
10+
errorHandler: (error: any, req: IncomingMessage, res: ServerResponse, next: (error: any) => void) => void
11+
requestHandler: (req: IncomingMessage, res: ServerResponse, next: (error?: any) => void) => void
12+
}
13+
714
export type IntegrationsConfiguration = Record<string, unknown>
815

916
export interface LazyConfiguration {

0 commit comments

Comments
 (0)