sentry-javascript
sentry-javascript copied to clipboard
On SSR client._captureRequestSession is not a function
Is there an existing issue for this?
- [X] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- [X] I have reviewed the documentation https://docs.sentry.io/
- [X] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Self-hosted/on-premise
Which SDK are you using?
@sentry/react
SDK Version
8.8.0
Framework Version
React 18.3.1
Link to Sentry event
No response
SDK Setup
const config = {
dsn,
environment: nodeEnv,
release: appReleaseName,
ignoreErrors: ['Failed to fetch', 'Connection disconnected', 'Network request failed', 'NetworkError', 'withrealtime/messaging'],
replaysSessionSampleRate: Number(process.env.SENTRY_REPLAYS_SESSION_SAMPLE_RATE) || 0.1,
replaysOnErrorSampleRate: Number(process.env.SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE) || 0.1,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.breadcrumbsIntegration({
console: true,
dom: true,
fetch: true,
history: true,
xhr: true,
}),
Sentry.globalHandlersIntegration({
onerror: true,
onunhandledrejection: true,
}),
Sentry.captureConsoleIntegration({
levels: ['error'],
}),
Sentry.replayIntegration({
maskAllText: false,
maskAllInputs: false,
blockAllMedia: false,
mask: ['[type="password"]'],
}),
],
sampleRate: Number(process.env.SENTRY_CLIENT_SAMPLE_RATE) || 0.1,
tracesSampleRate: Number(process.env.SENTRY_CLIENT_TRACES_SAMPLE_RATE) || 0.1,
normalizeDepth: 5,
};
Steps to Reproduce
Standard installation and use with SSR.
Expected Result
No errors
Actual Result
On SSR Uncaught Exception: TypeError: client._captureRequestSession is not a function after update to version 8.
Uncaught Exception: TypeError: client._captureRequestSession is not a function
{
arguments: [
Uncaught Exception:,
{
message: client._captureRequestSession is not a function,
name: TypeError,
stack: TypeError: client._captureRequestSession is not a function
at Immediate.<anonymous> (/xxx/node_modules/@sentry/node/cjs/integrations/http.js:109:45)
at process.processImmediate (node:internal/timers:478:21)
at process.callbackTrampoline (node:internal/async_hooks:130:17)
}
],
logger: console
}
Hi @Dima-Dim thanks for writing in!
_captureRequestSession is only available in server-side SDKs based on the ServerRuntimeClient. So the most prominent example would be @sentry/node or any SDK inheriting from @sentry/node.
According to the issue, you're using @sentry/react which uses BrowserClient and hence doesn't expose this method. ~Are you using a server Sentry SDK in addition?~ The stack trace tells me, you're also using @sentry/node. Would you mind sharing a bit more about your SSR setup?
Hi @Dima-Dim thanks for writing in!
_captureRequestSessionis only available in server-side SDKs based on theServerRuntimeClient. So the most prominent example would be@sentry/nodeor any SDK inheriting from@sentry/node. According to the issue, you're using@sentry/reactwhich usesBrowserClientand hence doesn't expose this method. ~Are you using a server Sentry SDK in addition?~ The stack trace tells me, you're also using@sentry/node. Would you mind sharing a bit more about your SSR setup?
Yes, using @sentry/node too.
"@sentry/node": "8.8.0",
Sentry.init({
enabled: process.env.SENTRY_SERVER_ENABLED !== 'false',
dsn,
environment: nodeEnv,
release: appRelease,
ignoreErrors: ['Failed to fetch', 'Connection disconnected', 'Network request failed', 'NetworkError', 'withrealtime/messaging'],
integrations: [
Sentry.captureConsoleIntegration(),
Sentry.extraErrorDataIntegration(5),
nodeProfilingIntegration(),
],
sampleRate: Number(process.env.SENTRY_SERVER_SAMPLE_RATE) || 0.1,
tracesSampleRate: Number(process.env.SENTRY_SERVER_TRACES_SAMPLE_RATE) || 0.1,
profilesSampleRate: Number(process.env.SENTRY_SERVER_PROFILES_SAMPLE_RATE) || 0.1,
normalizeDepth: 5,
});
I don't know anything about your SSR setup but what I think is happening is that you try to bundle the client-side @sentry/react into server side code or that somehow, the Node SDK is initialized but the browser client is already active from an earlier React SDK initialization on the server.
To debug this further, please provide detailed reproduction steps or - even better - a minimal reproduction example. Thanks!
I don’t even know what to provide, but I can say that this does not happen with the 7.110.1 version.
The error disappears if either do not use Sentry.setupExpressErrorHandler(app), or if do not use Sentry for the client '@sentry/react'.
If both are used, I get an error client._captureRequestSession is not a function on SSR. On the client (browser) there are no errors.
This makes generally sense but we don't know yet what kind of SSR setup you have (for example, are you using a framework like NextJS, something like Vite SSR or something custom?). This is important to know because it likely shows how this colission of the Node and React SDKs could happen.
To fix this, we need to know how we can reproduce this issue. So please provide
- either code and exact steps what to do to get to this error
- or a small repo (or zip file) with a minimal reproducible example that triggers this error.
I can't provide the application code yet, but judging by what I see in the issues section of Sentry, errors are coming there from node, although the code for connecting node is commented out.
I really think this happens because you are accidentally bundling code that is intended to run in Node.js into the client bundle. Try to make sure that nothing in your clientside code points to your server code.
Even though we'd love to help further without additional information, I think some kind of reproduction or the actual code is necessary for us to look into this more deeply!
I have the same problem, but in a Nuxt 3 module.
/module.ts
import {
defineNuxtModule,
addPlugin,
createResolver,
addServerPlugin,
} from "@nuxt/kit";
// Module options TypeScript interface definition
export interface ModuleOptions {}
export default defineNuxtModule<ModuleOptions>({
meta: {
name: "sentry-module",
configKey: "sentryModule",
},
// Default configuration options of the Nuxt module
defaults: {},
setup(_options, _nuxt) {
const { resolve } = createResolver(import.meta.url);
addPlugin(resolve("./runtime/plugin"));
addServerPlugin(resolve("./runtime/server/plugin"));
},
});
runtime/plugin.ts
import { defineNuxtPlugin } from "#imports";
import * as Sentry from "@sentry/vue";
export default defineNuxtPlugin((nuxtApp) => {
const dsn = process.env?.SENTRY_DSN;
if (!dsn) {
console.warn(
"Sentry DSN not set, skipping Sentry initialization - client."
);
return;
}
const frontendHostRegex = new RegExp(
`^https:\/\/${process.env.FRONTEND_HOST}`
);
Sentry.init({
app: nuxtApp.vueApp,
dsn,
logErrors: true,
release: `"${process.env.npm_package_name}@${process.env.npm_package_version}"`,
environment: process.env.NODE_ENV,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration({
maskAllText: false,
blockAllMedia: false,
}),
],
// Performance Monitoring
tracesSampleRate: 1.0, // Capture 100% of the transactions
// Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
tracePropagationTargets: ["localhost", frontendHostRegex],
// Session Replay
replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
});
});
runtime/server/plugin.ts
import { defineNitroPlugin } from "#imports";
import { H3Error } from "h3";
import * as Sentry from "@sentry/node";
import { nodeProfilingIntegration } from "@sentry/profiling-node";
export default defineNitroPlugin((nitroApp) => {
const dsn = process.env?.SENTRY_DSN;
if (!dsn) {
console.warn("Sentry DSN not set, skipping Sentry initialization - server");
return;
}
const frontendHostRegex = new RegExp(
`^https:\/\/${process.env.FRONTEND_HOST}`
);
Sentry.init({
dsn,
integrations: [
// Add our Profiling integration
nodeProfilingIntegration(),
],
release: `"${process.env.npm_package_name}@${process.env.npm_package_version}"`,
environment: process.env.NODE_ENV,
// Performance Monitoring
tracesSampleRate: 0.2,
// Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
tracePropagationTargets: ["localhost", frontendHostRegex],
// Set sampling rate for profiling - this is relative to tracesSampleRate
profilesSampleRate: 0.2,
});
nitroApp.hooks.hook("error", (error) => {
// Do not handle 404s and 422s
if (error instanceof H3Error) {
if (error.statusCode === 404 || error.statusCode === 422) {
return;
}
}
Sentry.captureException(error);
});
nitroApp.hooks.hook("request", (event) => {
event.context.$sentry = Sentry;
});
nitroApp.hooks.hookOnce("close", async () => {
await Sentry.close(2000);
});
});
@suku-kahanamoku also in your case, the reason is likely that you're bundling @sentry/node code into the client or perhaps @sentry/vue code into server JS files. I recommend checking for that.
You might want to check out our official @sentry/nuxt SDK. We're still actively working on this SDK (#9095) but we'd greatly appreciate some feedback if you want to give it a try.
For us to debug this, please provide a minimal reproduction example. Thank you!
I had a similar issue with the SvelteKit SDK and Vite when attempting to use replayIntegration().
I kept having the error [vite] Error when evaluating SSR module /src/hooks.client.ts: |- TypeError: __vite_ssr_import_0__.replayIntegration is not a function
In my case with SvelteKit and Vite, the solution was to add an environment guard (if (typeof window !== 'undefined')) in my hooks.client.ts file to ensure that it doesn't run on the server.
// hooks.client.ts
import * as Sentry from '@sentry/sveltekit';
if (typeof window !== 'undefined') {
import('@sentry/sveltekit').then(Sentry => {
dsn: '__DSN__',
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
integrations: [Sentry.replayIntegration()],
});
});
}
@othmanesghir sorry but this again looks like a different issue to me. Also I find this a bit weird given that the client hooks in SvelteKit should really only run in the client. If you can provide a minimal reproduction, please open a new issue.
In fact, I'm going to close this issue because we're now talking about three different frameworks and so far haven't received a minimal reproduction that reproduces the initial bug report. So far, we don't have concrete evidence that this is an SDK bug and not rather a bundling configuration issue.
To anyone following this issue: Please open a new one with a minimal reproducible exmaple so that we can properly debug this. Also, I'm happy to reopen this issue if there's a minimal repro for the original problem.
Thank you :)
I put Sentry.init inside an if condition that checks for the client, and now it works. ` import { defineNuxtPlugin, useRuntimeConfig } from "#imports"; import * as Sentry from "@sentry/vue";
export default defineNuxtPlugin((nuxtApp) => { const config = useRuntimeConfig(); const dsn = config.public?.SENTRY_DSN as string;
if (!dsn) { console.warn( "Sentry DSN not set, skipping Sentry initialization - client." ); return; }
const frontendHostRegex = new RegExp(
^https:\/\/${config.public?.FRONTEND_HOST}
);
if (import.meta.client) { Sentry.init({ app: nuxtApp.vueApp, dsn, logErrors: true, }); } });
`
Thanks everyone for the advice.
We have the same problem!
node server with @sentry/node to run the Vue app Vue app with @sentry/vue
Hi please be aware that closed issues don't necessarily receive the same level of attention as open ones. I will repeat what I said already multiple times:
If anyone following this issue can provide a minimal reproducible example of this problem, please open a new issue and we'll be happy to look into it. Considering we have various SDKs, frameworks and hence vastly diverse build setups this issue is not actionable for us.