Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP) Feat: Sentry Javascript V9 #4568

Open
wants to merge 22 commits into
base: v7
Choose a base branch
from
Open
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@

### Dependencies

- Bump JavaScript SDK from v8.54.0 to v9.1.0 ([#4568](https://github.com/getsentry/sentry-react-native/pull/4568))
- [changelog](https://github.com/getsentry/sentry-javascript/blob/9.1.0/CHANGELOG.md)
- [diff](https://github.com/getsentry/sentry-javascript/compare/8.54.0...9.1.0)
- Bump Android SDK from v7.20.1 to v7.22.0 ([#4529](https://github.com/getsentry/sentry-react-native/pull/4529))
- [changelog](https://github.com/getsentry/sentry-java/blob/7.x.x/CHANGELOG.md#7220)
- [diff](https://github.com/getsentry/sentry-java/compare/7.20.1...7.22.0)
Expand All @@ -44,6 +47,18 @@
- [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#2421)
- [diff](https://github.com/getsentry/sentry-cli/compare/2.41.1...2.42.1)


### Major Changes

- Remove autoSessionTracking option
- Remove `enableTracing` Instead, set tracesSampleRate: 0 to disable, or a higher value to enable it.
- Remove `getCurrentHub()`, `Hub`, and `getCurrentHubShim()`
- Remove `spanId` from propagation `context`
- Remove metrics API
- Remove `transactionContext` from `samplingContext`
- Remove deprecated `Request` type
- Remove `@sentry/utils` package, the exports were moved to `@sentry/core`

## 6.7.0

### Features
Expand Down
3 changes: 3 additions & 0 deletions dev-packages/type-check/ts3.8-test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ declare global {
interface IDBObjectStore {}
interface Window {
fetch: any;
setTimeout: any;
document: any;
}
interface ShadowRoot {}
interface BufferSource {}
Expand All @@ -19,6 +21,7 @@ declare global {
redirectCount: number;
}
interface PerformanceEntry {}
interface Performance {}
}
import 'react-native';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,6 @@ protected void getSentryAndroidOptions(
if (rnOptions.hasKey("sessionTrackingIntervalMillis")) {
options.setSessionTrackingIntervalMillis(rnOptions.getInt("sessionTrackingIntervalMillis"));
}
if (rnOptions.hasKey("shutdownTimeout")) {
options.setShutdownTimeoutMillis(rnOptions.getInt("shutdownTimeout"));
}
if (rnOptions.hasKey("enableNdkScopeSync")) {
options.setEnableScopeSync(rnOptions.getBoolean("enableNdkScopeSync"));
}
Expand Down
19 changes: 9 additions & 10 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,20 @@
},
"dependencies": {
"@sentry/babel-plugin-component-annotate": "3.1.2",
"@sentry/browser": "8.54.0",
"@sentry/browser": "9.1.0",
"@sentry/cli": "2.42.1",
"@sentry/core": "8.54.0",
"@sentry/react": "8.54.0",
"@sentry/types": "8.54.0",
"@sentry/utils": "8.54.0"
"@sentry/core": "9.1.0",
"@sentry/react": "9.1.0",
"@sentry/types": "9.1.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@expo/metro-config": "0.19.5",
"@mswjs/interceptors": "^0.25.15",
"@react-native/babel-preset": "0.77.1",
"@sentry-internal/eslint-config-sdk": "8.54.0",
"@sentry-internal/eslint-plugin-sdk": "8.54.0",
"@sentry-internal/typescript": "8.54.0",
"@sentry-internal/eslint-config-sdk": "9.1.0",
"@sentry-internal/eslint-plugin-sdk": "9.1.0",
"@sentry-internal/typescript": "9.1.0",
"@sentry/wizard": "3.42.0",
"@testing-library/react-native": "^12.7.2",
"@types/jest": "^29.5.13",
Expand All @@ -100,7 +99,7 @@
"eslint-plugin-react-native": "^3.8.1",
"expo": "^52.0.0",
"expo-module-scripts": "3.1.0",
"jest": "^29.6.2",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.6.2",
"jest-extended": "^4.0.2",
"madge": "^6.1.0",
Expand All @@ -110,7 +109,7 @@
"react-native": "0.77.1",
"react-test-renderer": "^18.3.1",
"rimraf": "^4.1.1",
"ts-jest": "^29.1.1",
"ts-jest": "^29.2.5",
"typescript": "4.9.5",
"uglify-js": "^3.17.4",
"uuid": "^9.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/plugin/src/withSentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface PluginProps {
const withSentryPlugin: ConfigPlugin<PluginProps | void> = (config, props) => {
const sentryProperties = getSentryProperties(props);

if (props && props.authToken) {
if (props?.authToken) {
// If not removed, the plugin config with the authToken will be written to the application package
delete props.authToken;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function withSentryAndroidGradlePlugin(
const withSentryProjectBuildGradle = (config: any): any => {
return withProjectBuildGradle(config, (projectBuildGradle: any) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!projectBuildGradle.modResults || !projectBuildGradle.modResults.contents) {
if (!projectBuildGradle.modResults?.contents) {
warnOnce('android/build.gradle content is missing or undefined.');
return config;
}
Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/js/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export type {
Breadcrumb,
Request,
SdkInfo,
Event,
Exception,
Expand Down Expand Up @@ -43,7 +42,6 @@ export {
getClient,
setCurrentClient,
addEventProcessor,
metricsDefault as metrics,
lastEventId,
} from '@sentry/core';

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/integrations/debugsymbolicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function replaceExceptionFramesInException(exception: Exception, frames: SentryS
* @param frames StackFrame[]
*/
function replaceThreadFramesInEvent(event: Event, frames: SentryStackFrame[]): void {
if (event.threads && event.threads.values && event.threads.values[0] && event.threads.values[0].stacktrace) {
if (event.threads?.values?.[0]?.stacktrace) {
event.threads.values[0].stacktrace.frames = frames.reverse();
}
}
Expand Down
5 changes: 1 addition & 4 deletions packages/core/src/js/integrations/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ export function getDefaultIntegrations(options: ReactNativeClientOptions): Integ
// hasTracingEnabled from `@sentry/core` only check if tracesSampler or tracesSampleRate keys are present
// that's different from prev imp here and might lead misconfiguration
// `tracesSampleRate: undefined` should not enable tracing
const hasTracingEnabled =
options.enableTracing ||
typeof options.tracesSampleRate === 'number' ||
typeof options.tracesSampler === 'function';
const hasTracingEnabled = typeof options.tracesSampleRate === 'number' || typeof options.tracesSampler === 'function';
if (hasTracingEnabled && options.enableAppStartTracking) {
integrations.push(appStartIntegration());
}
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/js/integrations/nativelinkederrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const nativeLinkedErrorsIntegration = (options: Partial<LinkedErrorsOptio
};

function preprocessEvent(event: Event, hint: EventHint | undefined, client: Client, limit: number, key: string): void {
if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
if (!event.exception?.values || !hint || !isInstanceOf(hint.originalException, Error)) {
return;
}

Expand Down Expand Up @@ -176,10 +176,10 @@ function exceptionFromAppleStackReturnAddresses(objCException: {
type: objCException.name,
value: objCException.message,
stacktrace: {
frames: (nativeStackFrames && nativeStackFrames.frames.reverse()) || [],
frames: nativeStackFrames?.frames.reverse() || [],
},
},
appleDebugImages: (nativeStackFrames && (nativeStackFrames.debugMetaImages as DebugImage[])) || [],
appleDebugImages: (nativeStackFrames?.debugMetaImages as DebugImage[]) || [],
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function setupErrorUtilsGlobalHandler(): void {
return;
}

const defaultHandler = errorUtils.getGlobalHandler && errorUtils.getGlobalHandler();
const defaultHandler = errorUtils.getGlobalHandler?.();

// eslint-disable-next-line @typescript-eslint/no-explicit-any
errorUtils.setGlobalHandler(async (error: any, isFatal?: boolean) => {
Expand Down Expand Up @@ -155,7 +155,8 @@ function setupErrorUtilsGlobalHandler(): void {
return;
}

void client.flush(client.getOptions().shutdownTimeout || 2000).then(
// shutdownTimeout was removed: https://github.com/getsentry/sentry-javascript/pull/15217
void client.flush(2000).then(
() => {
defaultHandler(error, isFatal);
},
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/js/integrations/screenshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ export const screenshotIntegration = (): Integration => {
};

async function processEvent(event: Event, hint: EventHint, client: ReactNativeClient): Promise<Event> {
const hasException = event.exception && event.exception.values && event.exception.values.length > 0;
const hasException = event.exception?.values?.length > 0;
if (!hasException || client.getOptions().beforeScreenshot?.(event, hint) === false) {
return event;
}

const screenshots: ScreenshotAttachment[] | null = await NATIVE.captureScreenshot();
if (screenshots && screenshots.length > 0) {
if (screenshots?.length > 0) {
hint.attachments = [...screenshots, ...(hint?.attachments || [])];
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/integrations/spotlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function getHostnameFromString(urlString: string): string | null {
const regex = /^(?:\w+:)?\/\/([^/:]+)(:\d+)?(.*)$/;
const matches = urlString.match(regex);

if (matches && matches[1]) {
if (matches?.[1]) {
return matches[1];
} else {
// Invalid URL format
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/integrations/viewhierarchy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const viewHierarchyIntegration = (): Integration => {
};

async function processEvent(event: Event, hint: EventHint): Promise<Event> {
const hasException = event.exception && event.exception.values && event.exception.values.length > 0;
const hasException = event.exception?.values?.length > 0;
if (!hasException) {
return event;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/profiling/convertHermesProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function mapStacks(
while (currentHermesFrameId !== undefined) {
const sentryFrameId = hermesStackFrameIdToSentryFrameIdMap.get(currentHermesFrameId);
sentryFrameId !== undefined && stack.push(sentryFrameId);
currentHermesFrameId = hermesStackFrames[currentHermesFrameId] && hermesStackFrames[currentHermesFrameId].parent;
currentHermesFrameId = hermesStackFrames[currentHermesFrameId]?.parent;
}
stacks.push(stack);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/profiling/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export const hermesProfilingIntegration = (initOptions: HermesProfilingOptions =
}

const client = getClient<ReactNativeClient>();
const options = client && client.getOptions();
const options = client?.getOptions?.();

const profilesSampleRate =
options && typeof options.profilesSampleRate === 'number' ? options.profilesSampleRate : undefined;
Expand Down
44 changes: 20 additions & 24 deletions packages/core/src/js/profiling/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ export function enrichCombinedProfileWithEventContext(
return null;
}

const trace_id = (event.contexts && event.contexts.trace && event.contexts.trace.trace_id) || '';
const trace_id = event.contexts?.trace?.trace_id || '';

// Log a warning if the profile has an invalid traceId (should be uuidv4).
// All profiles and transactions are rejected if this is the case and we want to
// warn users that this is happening if they enable debug flag
if (trace_id && trace_id.length !== 32) {
if (trace_id?.length !== 32) {
if (__DEV__) {
logger.log(`[Profiling] Invalid traceId: ${trace_id} on profiled event`);
}
Expand All @@ -97,25 +97,25 @@ export function enrichCombinedProfileWithEventContext(
release: event.release || '',
environment: event.environment || getDefaultEnvironment(),
os: {
name: (event.contexts && event.contexts.os && event.contexts.os.name) || '',
version: (event.contexts && event.contexts.os && event.contexts.os.version) || '',
build_number: (event.contexts && event.contexts.os && event.contexts.os.build) || '',
name: event.contexts?.os?.name || '',
version: event.contexts?.os?.version || '',
build_number: event.contexts?.os?.build || '',
},
device: {
locale: (event.contexts && event.contexts.device && (event.contexts.device.locale as string)) || '',
model: (event.contexts && event.contexts.device && event.contexts.device.model) || '',
manufacturer: (event.contexts && event.contexts.device && event.contexts.device.manufacturer) || '',
architecture: (event.contexts && event.contexts.device && event.contexts.device.arch) || '',
is_emulator: (event.contexts && event.contexts.device && event.contexts.device.simulator) || false,
locale: (event.contexts?.device && (event.contexts.device.locale as string)) || '',
model: event.contexts?.device?.model || '',
manufacturer: event.contexts?.device?.manufacturer || '',
architecture: event.contexts?.device?.arch || '',
is_emulator: event.contexts?.device?.simulator || false,
},
transaction: {
name: event.transaction || '',
id: event.event_id || '',
trace_id,
active_thread_id: (profile.transaction && profile.transaction.active_thread_id) || '',
active_thread_id: profile.transaction?.active_thread_id || '',
},
debug_meta: {
images: [...getDebugMetadata(), ...((profile.debug_meta && profile.debug_meta.images) || [])],
images: [...getDebugMetadata(), ...(profile.debug_meta?.images || [])],
},
};
}
Expand All @@ -136,19 +136,15 @@ export function enrichAndroidProfileWithEventContext(
build_id: profile.build_id || '',

device_cpu_frequencies: [],
device_is_emulator: (event.contexts && event.contexts.device && event.contexts.device.simulator) || false,
device_locale: (event.contexts && event.contexts.device && (event.contexts.device.locale as string)) || '',
device_manufacturer: (event.contexts && event.contexts.device && event.contexts.device.manufacturer) || '',
device_model: (event.contexts && event.contexts.device && event.contexts.device.model) || '',
device_os_name: (event.contexts && event.contexts.os && event.contexts.os.name) || '',
device_os_version: (event.contexts && event.contexts.os && event.contexts.os.version) || '',
device_is_emulator: event.contexts?.device?.simulator || false,
device_locale: (event.contexts?.device && (event.contexts.device.locale as string)) || '',
device_manufacturer: event.contexts?.device?.manufacturer || '',
device_model: event.contexts?.device?.model || '',
device_os_name: event.contexts?.os?.name || '',
device_os_version: event.contexts?.os?.version || '',

device_physical_memory_bytes:
(event.contexts &&
event.contexts.device &&
event.contexts.device.memory_size &&
Number(event.contexts.device.memory_size).toString(10)) ||
'',
(event.contexts?.device?.memory_size && Number(event.contexts.device.memory_size).toString(10)) || '',

environment: event.environment || getDefaultEnvironment(),

Expand All @@ -161,7 +157,7 @@ export function enrichAndroidProfileWithEventContext(

transaction_id: event.event_id || '',
transaction_name: event.transaction || '',
trace_id: (event.contexts && event.contexts.trace && event.contexts.trace.trace_id) || '',
trace_id: event.contexts?.trace?.trace_id || '',

version_name: event.release || '',
version_code: event.dist || '',
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/replay/CustomMask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const UnmaskFallback = (viewProps: ViewProps): React.ReactElement => {
return <View {...viewProps} />;
};

const hasViewManagerConfig = (nativeComponentName: string): boolean => UIManager.hasViewManagerConfig && UIManager.hasViewManagerConfig(nativeComponentName);
const hasViewManagerConfig = (nativeComponentName: string): boolean => UIManager.hasViewManagerConfig?.(nativeComponentName);

const Mask = ((): HostComponent<ViewProps> | React.ComponentType<ViewProps> => {
if (!hasViewManagerConfig(MaskNativeComponentName)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/replay/mobilereplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const mobileReplayIntegration = (initOptions: MobileReplayOptions = defau
const options = { ...defaultOptions, ...initOptions };

async function processEvent(event: Event): Promise<Event> {
const hasException = event.exception && event.exception.values && event.exception.values.length > 0;
const hasException = event.exception?.values?.length > 0;
if (!hasException) {
// Event is not an error, will not capture replay
return event;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/js/sdk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export function wrap<P extends Record<string, unknown>>(
const profilerProps = {
...(options?.profilerProps ?? {}),
name: RootComponent.displayName ?? 'Root',
updateProps: {}
};

const RootApp: React.FC<P> = (appProps) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/js/tools/metroconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export function withSentryBabelTransformer(
config: MetroConfig,
annotateReactComponents: true | { ignoredComponents?: string[] },
): MetroConfig {
const defaultBabelTransformerPath = config.transformer && config.transformer.babelTransformerPath;
const defaultBabelTransformerPath = config.transformer?.babelTransformerPath;
logger.debug('Default Babel transformer path from `config.transformer`:', defaultBabelTransformerPath);

if (!defaultBabelTransformerPath) {
Expand Down Expand Up @@ -270,10 +270,10 @@ export function withSentryFramesCollapsed(config: MetroConfig): MetroConfig {
originalCustomization: MetroCustomizeFrame | undefined,
): MetroCustomizeFrame => ({
...originalCustomization,
collapse: (originalCustomization && originalCustomization.collapse) || collapseSentryInternalFrames(frame),
collapse: originalCustomization?.collapse || collapseSentryInternalFrames(frame),
});

const maybePromiseCustomization = (originalCustomizeFrame && originalCustomizeFrame(frame)) || undefined;
const maybePromiseCustomization = originalCustomizeFrame?.(frame) || undefined;

if (maybePromiseCustomization !== undefined && 'then' in maybePromiseCustomization) {
return maybePromiseCustomization.then<MetroCustomizeFrame>(originalCustomization =>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/js/tracing/integrations/appStart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export const appStartIntegration = ({
return;
}

if (!event.contexts || !event.contexts.trace) {
if (!event.contexts?.trace) {
logger.warn('[AppStart] Transaction event is missing trace context. Can not attach app start.');
return;
}
Expand Down
Loading
Loading