Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
dsn: process.env.E2E_TEST_DSN,
tunnel: 'http://localhost:3031/', // proxy server
autoInstrumentRemix: true, // auto instrument Remix
integrations: [Sentry.nativeNodeFetchIntegration()],
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Sentry.init({
dsn: process.env.E2E_TEST_DSN,
tunnel: 'http://localhost:3031/', // proxy server
sendDefaultPii: true, // Testing the FormData
autoInstrumentRemix: true, // auto instrument Remix
captureActionFormDataKeys: {
file: true,
text: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
dsn: process.env.E2E_TEST_DSN,
tunnel: 'http://localhost:3031/', // proxy server
autoInstrumentRemix: true, // auto instrument Remix
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
dsn: process.env.E2E_TEST_DSN,
tunnel: 'http://localhost:3031/', // proxy server
autoInstrumentRemix: true, // auto instrument Remix
});
10 changes: 2 additions & 8 deletions packages/remix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
"access": "public"
},
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@remix-run/router": "1.x",
"@sentry/cli": "^2.39.1",
"@sentry/core": "8.45.0",
Expand Down Expand Up @@ -91,15 +90,10 @@
"fix": "eslint . --format stylish --fix",
"lint": "eslint . --format stylish",
"test": "yarn test:unit",
"test:integration": "run-s test:integration:otel test:integration:legacy",
"test:integration:otel": "export USE_OTEL=1 && run-s test:integration:v1 test:integration:v2",
"test:integration:legacy": "export USE_OTEL=0 && run-s test:integration:v1 test:integration:v2",
"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 && yarn test:integration:v1",
"test:integration:ci": "run-s test:integration:ci:otel test:integration:ci:legacy",
"test:integration:ci:otel": "USE_OTEL=1 yarn test:integration:ci:common",
"test:integration:ci:legacy": "USE_OTEL=0 yarn test:integration:ci:common",
"test:integration:ci:common": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server",
"test:integration:ci": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server",
"test:integration:prepare": "(cd test/integration && yarn install)",
"test:integration:clean": "(cd test/integration && rimraf .cache node_modules build)",
"test:integration:client": "yarn playwright install-deps && yarn playwright test test/integration/test/client/ --project='chromium'",
Expand Down
2 changes: 1 addition & 1 deletion packages/remix/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const config: PlaywrightTestConfig = {
workers: process.env.CI ? 3 : undefined,
webServer: {
env: {
NODE_OPTIONS: process.env.USE_OTEL === '1' ? '--require ./instrument.server.cjs' : '',
NODE_OPTIONS: '--require ./instrument.server.cjs',
},
command: '(cd test/integration/ && yarn build && yarn start)',
port: 3000,
Expand Down
10 changes: 5 additions & 5 deletions packages/remix/src/client/performance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,27 @@ import * as React from 'react';
import { DEBUG_BUILD } from '../utils/debug-build';
import { getFutureFlagsBrowser, readRemixVersionFromLoader } from '../utils/futureFlags';

export type Params<Key extends string = string> = {
type Params<Key extends string = string> = {
readonly [key in Key]: string | undefined;
};

export interface RouteMatch<ParamKey extends string = string> {
interface RouteMatch<ParamKey extends string = string> {
params: Params<ParamKey>;
pathname: string;
id: string;
handle: unknown;
}
export type UseEffect = (cb: () => void, deps: unknown[]) => void;
type UseEffect = (cb: () => void, deps: unknown[]) => void;

export type UseLocation = () => {
type UseLocation = () => {
pathname: string;
search?: string;
hash?: string;
state?: unknown;
key?: unknown;
};

export type UseMatches = () => RouteMatch[] | null;
type UseMatches = () => RouteMatch[] | null;

export type RemixBrowserTracingIntegrationOptions = Partial<Parameters<typeof originalBrowserTracingIntegration>[0]> & {
useEffect?: UseEffect;
Expand Down
5 changes: 2 additions & 3 deletions packages/remix/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,7 @@ export function getRemixDefaultIntegrations(options: RemixOptions): Integration[
return [
...getDefaultNodeIntegrations(options as NodeOptions).filter(integration => integration.name !== 'Http'),
httpIntegration(),
// eslint-disable-next-line deprecation/deprecation
options.autoInstrumentRemix ? remixIntegration() : undefined,
remixIntegration(),
].filter(int => int) as Integration[];
}

Expand Down Expand Up @@ -186,7 +185,7 @@ export function init(options: RemixOptions): NodeClient | undefined {

const client = nodeInit(options as NodeOptions);

instrumentServer(options);
instrumentServer();

return client;
}
67 changes: 5 additions & 62 deletions packages/remix/src/utils/errors.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import type { AppData, DataFunctionArgs, EntryContext, HandleDocumentRequestFunction } from '@remix-run/node';
import type { AppData, DataFunctionArgs } from '@remix-run/node';
import {
addExceptionMechanism,
captureException,
getClient,
handleCallbackErrors,
isPrimitive,
logger,
objectify,
winterCGRequestToRequestData,
} from '@sentry/core';
import type { RequestEventData, Span } from '@sentry/core';
import type { RequestEventData } from '@sentry/core';
import { DEBUG_BUILD } from './debug-build';
import type { RemixOptions } from './remixOptions';
import { storeFormDataKeys } from './utils';
import { extractData, isResponse, isRouteErrorResponse } from './vendor/response';
import type { DataFunction, RemixRequest } from './vendor/types';
import type { DataFunction } from './vendor/types';

/**
* Captures an exception happened in the Remix server.
Expand Down Expand Up @@ -76,48 +72,6 @@ export async function captureRemixServerException(
return scope;
});
}

/**
* Wraps the original `HandleDocumentRequestFunction` with error handling.
*
* @param origDocumentRequestFunction The original `HandleDocumentRequestFunction`.
* @param requestContext The request context.
* @param isRemixV2 Whether the Remix version is v2 or not.
*
* @returns The wrapped `HandleDocumentRequestFunction`.
*/
export function errorHandleDocumentRequestFunction(
this: unknown,
origDocumentRequestFunction: HandleDocumentRequestFunction,
requestContext: {
request: RemixRequest;
responseStatusCode: number;
responseHeaders: Headers;
context: EntryContext;
loadContext?: Record<string, unknown>;
},
isRemixV2: boolean,
): HandleDocumentRequestFunction {
const { request, responseStatusCode, responseHeaders, context, loadContext } = requestContext;

return handleCallbackErrors(
() => {
return origDocumentRequestFunction.call(this, request, responseStatusCode, responseHeaders, context, loadContext);
},
err => {
// This exists to capture the server-side rendering errors on Remix v1
// On Remix v2, we capture SSR errors at `handleError`
// We also skip primitives here, as we can't dedupe them, and also we don't expect any primitive SSR errors.
if (!isRemixV2 && !isPrimitive(err)) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
captureRemixServerException(err, 'documentRequest', request, isRemixV2);
}

throw err;
},
);
}

/**
* Wraps the original `DataFunction` with error handling.
* This function also stores the form data keys if the action is being called.
Expand All @@ -135,26 +89,15 @@ export async function errorHandleDataFunction(
origFn: DataFunction,
name: string,
args: DataFunctionArgs,
isRemixV2: boolean,
span?: Span,
): Promise<Response | AppData> {
return handleCallbackErrors(
async () => {
if (name === 'action' && span) {
const options = getClient()?.getOptions() as RemixOptions;

if (options.sendDefaultPii && options.captureActionFormDataKeys) {
await storeFormDataKeys(args, span);
}
}

return origFn.call(this, args);
},
err => {
// On Remix v2, we capture all unexpected errors (except the `Route Error Response`s / Thrown Responses) in `handleError` function.
// We capture all unexpected errors (except the `Route Error Response`s / Thrown Responses) in `handleError` function.
// This is both for consistency and also avoid duplicates such as primitives like `string` or `number` being captured twice.
// Remix v1 does not have a `handleError` function, so we capture all errors here.
if (isRemixV2 ? isResponse(err) : true) {
if (isResponse(err)) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
captureRemixServerException(err, name, args.request, true);
}
Expand Down
13 changes: 1 addition & 12 deletions packages/remix/src/utils/futureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { GLOBAL_OBJ } from '@sentry/core';

import type { FutureConfig, ServerBuild } from './vendor/types';

export type EnhancedGlobal = typeof GLOBAL_OBJ & {
type EnhancedGlobal = typeof GLOBAL_OBJ & {
__remixContext?: {
future?: FutureConfig;
state?: {
Expand Down Expand Up @@ -30,17 +30,6 @@ export function getFutureFlagsBrowser(): FutureConfig | undefined {
return window.__remixContext.future;
}

/**
* Get the future flags from the Remix server build
*
* @param build The Remix server build
*
* @returns The future flags
*/
export function getFutureFlagsServer(build: ServerBuild): FutureConfig | undefined {
return build.future;
}

/**
* Learn Remix version from the server build object
* V2 Server builds have a non-optional `mode` property
Expand Down
Loading
Loading