Closed TheHolyWaffle closed 5 months ago
So what is the actual problem here? It seems that this is a problem with the env not supporting lazy loading properly. If this is not loaded in jest it's probably not a problem, or are you actually having a problem because of this in your app? Is this only happening in test env, for example?
Hi @mydea Apologies if this isn't well defined.
For more context, I maintain a beforeBreadcrumb
function in our company and I'd like to test it's behavior using jest. I leverage sentry-testkit
for that but I noticed the breadcrumbs are not coming through anymore when upgrading from v7 to v8.
The reason it fails is because it fails to load the native node fetch integration during the jest beforeEach
. (The stacktrace from above). I'd like to get this functioning again 🙏
Here's the bigger context:
import { beforeBreadcrumb } from './before-breadcrumb';
import * as Sentry from '@sentry/node';
import sentryTestkit from 'sentry-testkit';
describe('integration test', () => {
const { testkit, sentryTransport } = sentryTestkit();
beforeAll(() => {
Sentry.init({
dsn: 'https://00000000000000000000000000000000@0000000.ingest.us.sentry.io/0000000',
transport: sentryTransport,
beforeBreadcrumb: beforeBreadcrumb,
integrations: [Sentry.nativeNodeFetchIntegration()],
});
});
beforeEach(() => testkit.reset());
afterEach(() => Sentry.getCurrentScope().clearBreadcrumbs());
it('should work for native node fetch', async () => {
await fetch('http://example.com/fetch', {
headers: {
'My-custom-header': 'foo',
'My-Custom-Header-2': ['foo', 'bar'],
},
});
Sentry.captureException(new Error('foo'));
await Sentry.flush();
expect(testkit.reports()).toHaveLength(1);
expect(testkit.reports()[0]!.breadcrumbs[0]).toStrictEqual({
timestamp: expect.any(Number),
category: 'http',
data: {
'http.method': 'GET',
status_code: 200,
url: 'http://example.com/fetch',
'http.header.My-custom-header': 'foo',
'http.header.My-Custom-Header-2': 'foo,bar',
'http.header.accept': '*/*',
'http.header.accept-language': '*',
'http.header.sec-fetch-mode': 'cors',
'http.header.user-agent': 'node',
'http.header.accept-encoding': expect.any(String),
'http.header.sentry-trace': expect.any(String),
'http.header.baggage': expect.any(String),
},
type: 'http',
});
});
});
Ah, OK, I can see the problem now.
Honestly I don't think there is an easy way to solve this in the SDK side of things 🤔 did you try to follow docs in jest here: https://jestjs.io/docs/ecmascript-modules for this?
I can run the tests using NODE_OPTIONS=--experimental-vm-modules npx jest
which makes it succeed.
But I'm wondering if this isn't also an issue in other cjs environments (besides Jest) where one might forget to use the --experimental-vm-modules
flag?
I can run the tests using
NODE_OPTIONS=--experimental-vm-modules npx jest
which makes it succeed.But I'm wondering if this isn't also an issue in other cjs environments (besides Jest) where one might forget to use the
--experimental-vm-modules
flag?
So this should work just fine in true cjs apps (we have a bunch of tests covering this, and this is actually what makes this work normally for almost all apps, as the vast majority of apps out there is running in CJS mode as of now). I think it's really just a jest issue which does not properly support all of these things (yet), unfortunately 🤔 See https://github.com/getsentry/sentry-javascript/pull/12137 for tests for this, which all run in CJS.
It's good to know that this flag fixes it, at least! 🙏
I would close this issue for now as there really isn't much we can do about this I believe!
I agree, this is jest
specific problem and using the vm flag fixes it. I should really spend the time to switch to something like vitest
....
Thanks for spending some time on this anyway 🙏 @mydea
Is there an existing issue for this?
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/node
SDK Version
8.4.0
Framework Version
No response
Link to Sentry event
No response
SDK Setup
Steps to Reproduce
jest
node_modules/@sentry/node/cjs/integrations/node-fetch.js
on the lineconst pkg = await import('opentelemetry-instrumentation-fetch-node');
Expected Result
It correctly imports
opentelemetry-instrumentation-fetch-node
without throwing an error in cjs modeActual Result
It throws an error