diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c4122a129a8b..dc20986c90ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -871,7 +871,7 @@ jobs: yarn test job_remix_integration_tests: - name: Remix v${{ matrix.remix }} (Node ${{ matrix.node }}) ${{ matrix.tracingIntegration && 'TracingIntegration'}} Tests + name: Remix v${{ matrix.remix }} (Node ${{ matrix.node }}) Tests needs: [job_get_metadata, job_build] if: needs.job_get_metadata.outputs.changed_remix == 'true' || github.event_name != 'pull_request' runs-on: ubuntu-20.04 diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/app/entry.server.tsx b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/app/entry.server.tsx index d228a7606ac6..5e0608ff5749 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/app/entry.server.tsx +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/app/entry.server.tsx @@ -1,10 +1,18 @@ +import * as Sentry from '@sentry/remix'; + +Sentry.init({ + tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: process.env.E2E_TEST_DSN, + tunnel: 'http://localhost:3031/', // proxy server +}); + import { PassThrough } from 'node:stream'; import type { AppLoadContext, EntryContext } from '@remix-run/node'; import { createReadableStreamFromReadable } from '@remix-run/node'; import { installGlobals } from '@remix-run/node'; import { RemixServer } from '@remix-run/react'; -import * as Sentry from '@sentry/remix'; import * as isbotModule from 'isbot'; import { renderToPipeableStream } from 'react-dom/server'; @@ -12,14 +20,6 @@ installGlobals(); const ABORT_DELAY = 5_000; -Sentry.init({ - environment: 'qa', // dynamic sampling bias to keep transactions - dsn: process.env.E2E_TEST_DSN, - // Performance Monitoring - tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! - tunnel: 'http://localhost:3031/', // proxy server -}); - export const handleError = Sentry.wrapRemixHandleError; export default function handleRequest( diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/tests/behaviour-server.test.ts b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/tests/behaviour-server.test.ts index 6a36f85cbfd0..09cee3ca79bc 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/tests/behaviour-server.test.ts +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/tests/behaviour-server.test.ts @@ -7,7 +7,13 @@ test('Sends two linked transactions (server & client) to Sentry', async ({ page // We use this to identify the transactions const testTag = uuid4(); - // no server span here! + const httpServerTransactionPromise = waitForTransaction('create-remix-app-express-vite-dev', transactionEvent => { + return ( + transactionEvent.type === 'transaction' && + transactionEvent.contexts?.trace?.op === 'http.server' && + transactionEvent.tags?.['sentry_test'] === testTag + ); + }); const pageLoadTransactionPromise = waitForTransaction('create-remix-app-express-vite-dev', transactionEvent => { return ( @@ -20,16 +26,25 @@ test('Sends two linked transactions (server & client) to Sentry', async ({ page page.goto(`/?tag=${testTag}`); const pageloadTransaction = await pageLoadTransactionPromise; + const httpServerTransaction = await httpServerTransactionPromise; expect(pageloadTransaction).toBeDefined(); + expect(httpServerTransaction).toBeDefined(); + + const httpServerTraceId = httpServerTransaction.contexts?.trace?.trace_id; + const httpServerSpanId = httpServerTransaction.contexts?.trace?.span_id; const pageLoadTraceId = pageloadTransaction.contexts?.trace?.trace_id; const pageLoadSpanId = pageloadTransaction.contexts?.trace?.span_id; const pageLoadParentSpanId = pageloadTransaction.contexts?.trace?.parent_span_id; + expect(httpServerTransaction.transaction).toBe('routes/_index'); expect(pageloadTransaction.transaction).toBe('routes/_index'); - expect(pageLoadTraceId).toBeDefined(); - expect(pageLoadParentSpanId).toBeUndefined(); - expect(pageLoadSpanId).toBeDefined(); + expect(httpServerTraceId).toBeDefined(); + expect(httpServerSpanId).toBeDefined(); + + expect(pageLoadTraceId).toEqual(httpServerTraceId); + expect(pageLoadParentSpanId).toEqual(httpServerSpanId); + expect(pageLoadSpanId).not.toEqual(httpServerSpanId); }); diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/app/entry.server.tsx b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/app/entry.server.tsx index 98ab60159b70..0f4ea48a99e9 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/app/entry.server.tsx +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/app/entry.server.tsx @@ -1,3 +1,12 @@ +import * as Sentry from '@sentry/remix'; + +Sentry.init({ + tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: process.env.E2E_TEST_DSN, + tunnel: 'http://localhost:3031/', // proxy server +}); + /** * By default, Remix will handle generating the HTTP Response for you. * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ @@ -10,7 +19,6 @@ import type { AppLoadContext, EntryContext } from '@remix-run/node'; import { createReadableStreamFromReadable } from '@remix-run/node'; import { installGlobals } from '@remix-run/node'; import { RemixServer } from '@remix-run/react'; -import * as Sentry from '@sentry/remix'; import isbot from 'isbot'; import { renderToPipeableStream } from 'react-dom/server'; @@ -18,14 +26,6 @@ installGlobals(); const ABORT_DELAY = 5_000; -Sentry.init({ - environment: 'qa', // dynamic sampling bias to keep transactions - dsn: process.env.E2E_TEST_DSN, - // Performance Monitoring - tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! - tunnel: 'http://localhost:3031/', // proxy server -}); - export const handleError = Sentry.wrapRemixHandleError; export default function handleRequest( diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx b/dev-packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx index 03364b7d1f32..b0f1c5d19f09 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx +++ b/dev-packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx @@ -1,3 +1,12 @@ +import * as Sentry from '@sentry/remix'; + +Sentry.init({ + tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: process.env.E2E_TEST_DSN, + tunnel: 'http://localhost:3031/', // proxy server +}); + /** * By default, Remix will handle generating the HTTP Response for you. * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ @@ -9,20 +18,11 @@ import { PassThrough } from 'node:stream'; import type { AppLoadContext, EntryContext } from '@remix-run/node'; import { Response } from '@remix-run/node'; import { RemixServer } from '@remix-run/react'; -import * as Sentry from '@sentry/remix'; import isbot from 'isbot'; import { renderToPipeableStream } from 'react-dom/server'; const ABORT_DELAY = 5_000; -Sentry.init({ - environment: 'qa', // dynamic sampling bias to keep transactions - dsn: process.env.E2E_TEST_DSN, - // Performance Monitoring - tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production! - tunnel: 'http://localhost:3031/', // proxy server -}); - export const handleError = Sentry.wrapRemixHandleError; export default function handleRequest( diff --git a/dev-packages/e2e-tests/test-applications/node-exports-test-app/scripts/consistentExports.ts b/dev-packages/e2e-tests/test-applications/node-exports-test-app/scripts/consistentExports.ts index 99d2ed614d2b..c238cf326d68 100644 --- a/dev-packages/e2e-tests/test-applications/node-exports-test-app/scripts/consistentExports.ts +++ b/dev-packages/e2e-tests/test-applications/node-exports-test-app/scripts/consistentExports.ts @@ -71,7 +71,7 @@ const DEPENDENTS: Dependent[] = [ }, { package: '@sentry/remix', - compareWith: nodeExperimentalExports, + compareWith: nodeExports, exports: Object.keys(SentryRemix), }, { diff --git a/packages/astro/src/index.types.ts b/packages/astro/src/index.types.ts index 3719a2d5ecea..dad62a288d53 100644 --- a/packages/astro/src/index.types.ts +++ b/packages/astro/src/index.types.ts @@ -24,7 +24,6 @@ export declare function flush(timeout?: number | undefined): PromiseLike/build/', '/node_modules/', '/test/integration/'], + // Some tests take longer to finish, as flushing spans with OpenTelemetry takes some more time + testTimeout: 15000, }; diff --git a/packages/remix/package.json b/packages/remix/package.json index 8cc0ce185345..b115b93b9ccd 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -48,7 +48,8 @@ "@remix-run/router": "1.x", "@sentry/cli": "^2.30.0", "@sentry/core": "8.0.0-alpha.2", - "@sentry/node-experimental": "8.0.0-alpha.2", + "@sentry/node": "8.0.0-alpha.2", + "@sentry/opentelemetry": "8.0.0-alpha.2", "@sentry/react": "8.0.0-alpha.2", "@sentry/types": "8.0.0-alpha.2", "@sentry/utils": "8.0.0-alpha.2", @@ -82,7 +83,7 @@ "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", "test": "yarn test:unit", - "test:integration": "run-s test:integration:v1 test:integration:v2 test:integration:tracingIntegration", + "test:integration": "run-s test:integration:v1 test:integration:v2", "test:integration:v1": "run-s test:integration:clean test:integration:prepare test:integration:client test:integration:server", "test:integration:v2": "export REMIX_VERSION=2 && run-s test:integration:v1", "test:integration:ci": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server", diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index 3ed510a5bb7b..fcdf56eb2a57 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -1,6 +1,6 @@ -import { applySdkMetadata } from '@sentry/core'; -import type { NodeOptions } from '@sentry/node-experimental'; -import { getClient, init as nodeInit, setTag } from '@sentry/node-experimental'; +import { applySdkMetadata, isInitialized } from '@sentry/core'; +import type { NodeOptions } from '@sentry/node'; +import { init as nodeInit, setTag } from '@sentry/node'; import { logger } from '@sentry/utils'; import { DEBUG_BUILD } from './utils/debug-build'; @@ -10,8 +10,6 @@ import type { RemixOptions } from './utils/remixOptions'; // We need to explicitly export @sentry/node as they end up under `default` in ESM builds // See: https://github.com/getsentry/sentry-javascript/issues/8474 export { - // eslint-disable-next-line deprecation/deprecation - addGlobalEventProcessor, addEventProcessor, addBreadcrumb, addIntegration, @@ -22,8 +20,6 @@ export { captureMessage, createTransport, // eslint-disable-next-line deprecation/deprecation - getActiveTransaction, - // eslint-disable-next-line deprecation/deprecation getCurrentHub, getClient, getCurrentScope, @@ -46,7 +42,6 @@ export { setHttpStatus, withScope, withIsolationScope, - autoDiscoverNodePerformanceMonitoringIntegrations, makeNodeTransport, getDefaultIntegrations, defaultStackParser, @@ -56,7 +51,6 @@ export { addRequestDataToEvent, DEFAULT_USER_INCLUDES, extractRequestData, - Integrations, consoleIntegration, onUncaughtExceptionIntegration, onUnhandledRejectionIntegration, @@ -68,7 +62,6 @@ export { functionToStringIntegration, inboundFiltersIntegration, linkedErrorsIntegration, - Handlers, setMeasurement, getActiveSpan, getRootSpan, @@ -83,15 +76,30 @@ export { parameterize, metrics, createGetModuleFromFilename, - hapiErrorPlugin, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, -} from '@sentry/node-experimental'; + expressIntegration, + expressErrorHandler, + setupExpressErrorHandler, + fastifyIntegration, + graphqlIntegration, + mongoIntegration, + mongooseIntegration, + mysqlIntegration, + mysql2Integration, + nestIntegration, + postgresIntegration, + prismaIntegration, + hapiIntegration, + setupHapiErrorHandler, + spotlightIntegration, + setupFastifyErrorHandler, +} from '@sentry/node'; // Keeping the `*` exports for backwards compatibility and types -export * from '@sentry/node-experimental'; +export * from '@sentry/node'; export { captureRemixServerException, wrapRemixHandleError } from './utils/instrumentServer'; export { ErrorBoundary, withErrorBoundary } from '@sentry/react'; @@ -102,15 +110,11 @@ export { wrapExpressCreateRequestHandler } from './utils/serverAdapters/express' export type { SentryMetaArgs } from './utils/types'; -function sdkAlreadyInitialized(): boolean { - return !!getClient(); -} - /** Initializes Sentry Remix SDK on Node. */ export function init(options: RemixOptions): void { applySdkMetadata(options, 'remix', ['remix', 'node']); - if (sdkAlreadyInitialized()) { + if (isInitialized()) { DEBUG_BUILD && logger.log('SDK already initialized'); return; diff --git a/packages/remix/src/index.types.ts b/packages/remix/src/index.types.ts index 5835c05b2c71..a4c619401d9d 100644 --- a/packages/remix/src/index.types.ts +++ b/packages/remix/src/index.types.ts @@ -14,7 +14,7 @@ export declare function init(options: RemixOptions): void; // We export a merged Integrations object so that users can (at least typing-wise) use all integrations everywhere. // eslint-disable-next-line deprecation/deprecation -export declare const Integrations: typeof clientSdk.Integrations & typeof serverSdk.Integrations; +export declare const Integrations: typeof clientSdk.Integrations; export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration; export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration; @@ -27,6 +27,13 @@ export declare const defaultStackParser: StackParser; // methods from `@sentry/core`. declare const runtime: 'client' | 'server'; +// eslint-disable-next-line deprecation/deprecation +export declare const makeMain: typeof clientSdk.makeMain; +// eslint-disable-next-line deprecation/deprecation +export declare const getCurrentHub: typeof clientSdk.getCurrentHub; +export declare const getClient: typeof clientSdk.getClient; +export declare const continueTrace: typeof clientSdk.continueTrace; + export const close = runtime === 'client' ? clientSdk.close : serverSdk.close; export const flush = runtime === 'client' ? clientSdk.flush : serverSdk.flush; diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index bd8f0e0e801e..419e5e4ba0f2 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -3,9 +3,11 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + captureException, continueTrace, + getActiveSpan, getClient, - getDynamicSamplingContextFromSpan, + getRootSpan, handleCallbackErrors, hasTracingEnabled, setHttpStatus, @@ -14,7 +16,7 @@ import { startSpan, withIsolationScope, } from '@sentry/core'; -import { captureException, getActiveSpan, getRootSpan } from '@sentry/node-experimental'; +import { getDynamicSamplingContextFromSpan } from '@sentry/opentelemetry'; import type { Span, TransactionSource, WrappedFunction } from '@sentry/types'; import { addExceptionMechanism, diff --git a/packages/remix/src/utils/remixOptions.ts b/packages/remix/src/utils/remixOptions.ts index 6ac57b5a2f1e..4a1fe13e18e1 100644 --- a/packages/remix/src/utils/remixOptions.ts +++ b/packages/remix/src/utils/remixOptions.ts @@ -1,4 +1,4 @@ -import type { NodeOptions } from '@sentry/node-experimental'; +import type { NodeOptions } from '@sentry/node'; import type { BrowserOptions } from '@sentry/react'; import type { Options } from '@sentry/types'; diff --git a/packages/remix/src/utils/serverAdapters/express.ts b/packages/remix/src/utils/serverAdapters/express.ts index 27e599e677e7..51e3b40e0019 100644 --- a/packages/remix/src/utils/serverAdapters/express.ts +++ b/packages/remix/src/utils/serverAdapters/express.ts @@ -1,5 +1,5 @@ import { getClient, getCurrentHub, hasTracingEnabled, setHttpStatus, withIsolationScope } from '@sentry/core'; -import { flush } from '@sentry/node-experimental'; +import { flush } from '@sentry/node'; import type { Hub, Span } from '@sentry/types'; import { extractRequestData, fill, isString, logger } from '@sentry/utils'; diff --git a/packages/remix/test/index.server.test.ts b/packages/remix/test/index.server.test.ts index 71d2933f9d0e..20953ad32507 100644 --- a/packages/remix/test/index.server.test.ts +++ b/packages/remix/test/index.server.test.ts @@ -1,6 +1,6 @@ -import * as SentryNode from '@sentry/node-experimental'; +import * as SentryNode from '@sentry/node'; -import { Integrations, init } from '../src/index.server'; +import { init } from '../src/index.server'; const nodeInit = jest.spyOn(SentryNode, 'init'); @@ -55,9 +55,4 @@ describe('Server init()', () => { expect(SentryNode.getIsolationScope().getScopeData().tags).toEqual({ runtime: 'node' }); }); - - it('has both node and tracing integrations', () => { - expect(Integrations.Apollo).not.toBeUndefined(); - expect(Integrations.Http).not.toBeUndefined(); - }); }); diff --git a/packages/remix/test/integration/app_v1/entry.server.tsx b/packages/remix/test/integration/app_v1/entry.server.tsx index d7fcd6b1ea6b..d4ad53d80aec 100644 --- a/packages/remix/test/integration/app_v1/entry.server.tsx +++ b/packages/remix/test/integration/app_v1/entry.server.tsx @@ -1,7 +1,5 @@ -import type { EntryContext } from '@remix-run/node'; -import { RemixServer } from '@remix-run/react'; +// it is important this is first! import * as Sentry from '@sentry/remix'; -import { renderToString } from 'react-dom/server'; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', @@ -11,6 +9,10 @@ Sentry.init({ autoSessionTracking: false, }); +import type { EntryContext } from '@remix-run/node'; +import { RemixServer } from '@remix-run/react'; +import { renderToString } from 'react-dom/server'; + export default function handleRequest( request: Request, responseStatusCode: number, diff --git a/packages/remix/test/integration/app_v2/entry.server.tsx b/packages/remix/test/integration/app_v2/entry.server.tsx index bba366801092..6d539702e955 100644 --- a/packages/remix/test/integration/app_v2/entry.server.tsx +++ b/packages/remix/test/integration/app_v2/entry.server.tsx @@ -1,7 +1,5 @@ -import type { EntryContext } from '@remix-run/node'; -import { RemixServer } from '@remix-run/react'; +// it is important this is first! import * as Sentry from '@sentry/remix'; -import { renderToString } from 'react-dom/server'; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', @@ -11,6 +9,10 @@ Sentry.init({ autoSessionTracking: false, }); +import type { EntryContext } from '@remix-run/node'; +import { RemixServer } from '@remix-run/react'; +import { renderToString } from 'react-dom/server'; + export const handleError = Sentry.wrapRemixHandleError; export default function handleRequest( diff --git a/packages/remix/test/integration/package.json b/packages/remix/test/integration/package.json index c50b1c84d578..3d7cb377a74b 100644 --- a/packages/remix/test/integration/package.json +++ b/packages/remix/test/integration/package.json @@ -26,7 +26,6 @@ "@sentry/browser": "file:../../../browser", "@sentry/core": "file:../../../core", "@sentry/node": "file:../../../node-experimental", - "@sentry/node-experimental": "file:../../../node", "@sentry/opentelemetry": "file:../../../opentelemetry", "@sentry/react": "file:../../../react", "@sentry/replay": "file:../../../replay", diff --git a/packages/remix/test/integration/test/server/action.test.ts b/packages/remix/test/integration/test/server/action.test.ts index fe0b4a749c43..884c11c64657 100644 --- a/packages/remix/test/integration/test/server/action.test.ts +++ b/packages/remix/test/integration/test/server/action.test.ts @@ -61,7 +61,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada assertSentryTransaction(transaction[2], { contexts: { trace: { - status: 'internal_error', + status: 'unknown_error', data: { 'http.response.status_code': 500, }, @@ -169,7 +169,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'GET', 'http.response.status_code': 500, @@ -217,7 +217,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'POST', 'http.response.status_code': 500, @@ -265,7 +265,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'POST', 'http.response.status_code': 500, @@ -313,7 +313,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'POST', 'http.response.status_code': 500, @@ -361,7 +361,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'POST', 'http.response.status_code': 500, @@ -409,7 +409,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'POST', 'http.response.status_code': 500, @@ -457,7 +457,7 @@ describe.each(['builtin', 'express'])('Remix API Actions with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'POST', 'http.response.status_code': 500, diff --git a/packages/remix/test/integration/test/server/loader.test.ts b/packages/remix/test/integration/test/server/loader.test.ts index c40282096e18..6e1c41ae54b8 100644 --- a/packages/remix/test/integration/test/server/loader.test.ts +++ b/packages/remix/test/integration/test/server/loader.test.ts @@ -19,7 +19,7 @@ describe.each(['builtin', 'express'])('Remix API Loaders with adapter = %s', ada assertSentryTransaction(transaction, { contexts: { trace: { - status: 'internal_error', + status: 'unknown_error', data: { 'http.response.status_code': 500, }, @@ -51,8 +51,23 @@ describe.each(['builtin', 'express'])('Remix API Loaders with adapter = %s', ada const env = await RemixTestEnv.init(adapter); const url = `${env.url}/loader-throw-response/-1`; - const envelopes = await env.getMultipleEnvelopeRequest({ url, count: 1, envelopeType: ['event'] }); - const event = envelopes[0][2]; + // We also wait for the transaction, even though we don't care about it for this test + // but otherwise this may leak into another test + const envelopes = await env.getMultipleEnvelopeRequest({ url, count: 2, envelopeType: ['event', 'transaction'] }); + + const event = envelopes[0][2].type === 'transaction' ? envelopes[1][2] : envelopes[0][2]; + const transaction = envelopes[0][2].type === 'transaction' ? envelopes[0][2] : envelopes[1][2]; + + assertSentryTransaction(transaction, { + contexts: { + trace: { + status: 'unknown_error', + data: { + 'http.response.status_code': 500, + }, + }, + }, + }); assertSentryEvent(event, { exception: { @@ -133,7 +148,7 @@ describe.each(['builtin', 'express'])('Remix API Loaders with adapter = %s', ada contexts: { trace: { op: 'http.server', - status: 'internal_error', + status: 'unknown_error', data: { method: 'GET', 'http.response.status_code': 500, @@ -184,9 +199,7 @@ describe.each(['builtin', 'express'])('Remix API Loaders with adapter = %s', ada const val = key[key.length - 1]; expect(tags[key]).toEqual(val); }); - // express tests tend to take slightly longer on node >= 20 - // TODO: check why this is happening - }, 10000); + }); it('continues transaction from sentry-trace header and baggage', async () => { const env = await RemixTestEnv.init(adapter); diff --git a/packages/remix/test/integration/test/server/ssr.test.ts b/packages/remix/test/integration/test/server/ssr.test.ts index 63b0fdf7d4cd..2e96760d2bae 100644 --- a/packages/remix/test/integration/test/server/ssr.test.ts +++ b/packages/remix/test/integration/test/server/ssr.test.ts @@ -13,7 +13,7 @@ describe('Server Side Rendering', () => { assertSentryTransaction(transaction[2], { contexts: { trace: { - status: 'internal_error', + status: 'unknown_error', data: { 'http.response.status_code': 500, },