Skip to content

Commit

Permalink
Merge branch 'antonis/rn-0.75.4-no-flipper' into antonis/rn-0.75.4-core
Browse files Browse the repository at this point in the history
  • Loading branch information
antonis committed Oct 15, 2024
2 parents 122417c + 49408ec commit abcf737
Show file tree
Hide file tree
Showing 22 changed files with 378 additions and 26 deletions.
1 change: 1 addition & 0 deletions .github/workflows/buildandtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- main
- v5
- release/**
pull_request:

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- main
- v5
- release/**
pull_request:

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ name: End-to-End Tests

on:
push:
branches: [main]
branches:
- main
- v5
- release/**
pull_request:

concurrency:
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/native-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ name: Native Tests

on:
push:
branches: [main]
branches:
- main
- v5
- release/**
pull_request:

jobs:
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/sample-application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ name: Sample Application

on:
push:
branches: [main]
branches:
- main
- v5
pull_request:

concurrency:
Expand Down
7 changes: 0 additions & 7 deletions .github/workflows/testflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ jobs:
node-version: 18
cache: 'yarn'
cache-dependency-path: yarn.lock
- uses: actions/cache@v4
id: deps-cache
with:
path: |
node_modules
samples/react-native/node_modules
key: ${{ github.workflow }}-${{ github.job }}-${{ hashFiles('yarn.lock', 'samples/react-native/yarn.lock') }}
- name: Install Dependencies
run: |
yarn install
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

### Fixes

- TimetoTisplay correctly warns about not supporting the new React Native architecture ([#4160](https://github.com/getsentry/sentry-react-native/pull/4160))
- Native Wrapper method `setContext` ensures only values convertible to NativeMap are passed ([#4168](https://github.com/getsentry/sentry-react-native/pull/4168))
- Native Wrapper method `setExtra` ensures only stringified values are passed ([#4168](https://github.com/getsentry/sentry-react-native/pull/4168))
- `setContext('key', null)` removes the key value also from platform context ([#4168](https://github.com/getsentry/sentry-react-native/pull/4168))

## 5.34.0

### Fixes

- Handles error with string cause ([#4163](https://github.com/getsentry/sentry-react-native/pull/4163))
- Use `appLaunchedInForeground` to determine invalid app start data on Android ([#4146](https://github.com/getsentry/sentry-react-native/pull/4146))

Expand Down
1 change: 1 addition & 0 deletions packages/core/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/ts3.8
/README.md
/package.tgz
Original file line number Diff line number Diff line change
Expand Up @@ -639,18 +639,29 @@ public void clearBreadcrumbs() {
}

public void setExtra(String key, String extra) {
if (key == null || extra == null) {
logger.log(SentryLevel.ERROR, "RNSentry.setExtra called with null key or value, can't change extra.");
return;
}

Sentry.configureScope(scope -> {
scope.setExtra(key, extra);
});
}

public void setContext(final String key, final ReadableMap context) {
if (key == null || context == null) {
if (key == null) {
logger.log(SentryLevel.ERROR, "RNSentry.setContext called with null key, can't change context.");
return;
}

Sentry.configureScope(scope -> {
final HashMap<String, Object> contextHashMap = context.toHashMap();
if (context == null) {
scope.removeContexts(key);
return;
}

final HashMap<String, Object> contextHashMap = context.toHashMap();
scope.setContexts(key, contextHashMap);
});
}
Expand Down
10 changes: 9 additions & 1 deletion packages/core/ios/RNSentry.mm
Original file line number Diff line number Diff line change
Expand Up @@ -587,8 +587,16 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray<NSNumber*>*)instructionsAdd
context:(NSDictionary *)context
)
{
if (key == nil) {
return;
}

[SentrySDK configureScope:^(SentryScope * _Nonnull scope) {
[scope setContextValue:context forKey:key];
if (context == nil) {
[scope removeContextForKey:key];
} else {
[scope setContextValue:context forKey:key];
}
}];
}

Expand Down
Binary file removed packages/core/package.tgz
Binary file not shown.
7 changes: 5 additions & 2 deletions packages/core/src/js/tracing/timetodisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Span,StartSpanOptions } from '@sentry/types';
import { fill, logger } from '@sentry/utils';
import * as React from 'react';

import { isTurboModuleEnabled } from '../utils/environment';
import { SPAN_ORIGIN_AUTO_UI_TIME_TO_DISPLAY, SPAN_ORIGIN_MANUAL_UI_TIME_TO_DISPLAY } from './origin';
import { getRNSentryOnDrawReporter, nativeComponentExists } from './timetodisplaynative';
import type {RNSentryOnDrawNextFrameEvent } from './timetodisplaynative.types';
Expand Down Expand Up @@ -60,12 +61,14 @@ function TimeToDisplay(props: {
fullDisplay?: boolean;
}): React.ReactElement {
const RNSentryOnDrawReporter = getRNSentryOnDrawReporter();
const isNewArchitecture = isTurboModuleEnabled();

if (__DEV__ && !nativeComponentMissingLogged && !nativeComponentExists) {
if (__DEV__ && (isNewArchitecture || (!nativeComponentExists && !nativeComponentMissingLogged))){
nativeComponentMissingLogged = true;
// Using setTimeout with a delay of 0 milliseconds to defer execution and avoid printing the React stack trace.
setTimeout(() => {
logger.warn('TimeToInitialDisplay and TimeToFullDisplay are not supported on the web, Expo Go and New Architecture. Run native build or report an issue at https://github.com/getsentry/sentry-react-native');
logger.warn(
'TimeToInitialDisplay and TimeToFullDisplay are not supported on the web, Expo Go and New Architecture. Run native build or report an issue at https://github.com/getsentry/sentry-react-native');
}, 0);
}

Expand Down
47 changes: 40 additions & 7 deletions packages/core/src/js/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type { NativeAndroidProfileEvent, NativeProfileEvent } from './profiling/
import type { MobileReplayOptions } from './replay/mobilereplay';
import type { RequiredKeysUser } from './user';
import { isTurboModuleEnabled } from './utils/environment';
import { convertToNormalizedObject } from './utils/normalize';
import { ReactNativeLibraries } from './utils/rnlibraries';
import { base64StringFromByteArray, utf8ToBytes } from './vendor';

Expand Down Expand Up @@ -84,7 +85,8 @@ interface SentryNativeWrapper {
enableNativeFramesTracking(): void;

addBreadcrumb(breadcrumb: Breadcrumb): void;
setContext(key: string, context: { [key: string]: unknown } | null): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setContext(key: string, context: { [key: string]: any } | null): void;
clearBreadcrumbs(): void;
setExtra(key: string, extra: unknown): void;
setUser(user: User | null): void;
Expand Down Expand Up @@ -396,10 +398,25 @@ export const NATIVE: SentryNativeWrapper = {
throw this._NativeClientError;
}

// we stringify the extra as native only takes in strings.
const stringifiedExtra = typeof extra === 'string' ? extra : JSON.stringify(extra);
if (typeof extra === 'string') {
return RNSentry.setExtra(key, extra);
}
if (typeof extra === 'undefined') {
return RNSentry.setExtra(key, 'undefined');
}

let stringifiedExtra: string | undefined;
try {
const normalizedExtra = normalize(extra);
stringifiedExtra = JSON.stringify(normalizedExtra);
} catch (e) {
logger.error('Extra for key ${key} not passed to native SDK, because it contains non-stringifiable values', e);
}

RNSentry.setExtra(key, stringifiedExtra);
if (typeof stringifiedExtra === 'string') {
return RNSentry.setExtra(key, stringifiedExtra);
}
return RNSentry.setExtra(key, '**non-stringifiable**');
},

/**
Expand Down Expand Up @@ -436,19 +453,35 @@ export const NATIVE: SentryNativeWrapper = {
},

/**
* Sets context on the native scope. Not implemented in Android yet.
* Sets context on the native scope.
* @param key string
* @param context key-value map
*/
setContext(key: string, context: { [key: string]: unknown } | null): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
setContext(key: string, context: { [key: string]: any } | null): void {
if (!this.enableNative) {
return;
}
if (!this._isModuleLoaded(RNSentry)) {
throw this._NativeClientError;
}

RNSentry.setContext(key, context !== null ? normalize(context) : null);
if (context === null) {
return RNSentry.setContext(key, null);
}

let normalizedContext: Record<string, unknown> | undefined;
try {
normalizedContext = convertToNormalizedObject(context);
} catch (e) {
logger.error('Context for key ${key} not passed to native SDK, because it contains non-serializable values', e);
}

if (normalizedContext) {
RNSentry.setContext(key, normalizedContext);
} else {
RNSentry.setContext(key, { error: '**non-serializable**' });
}
},

/**
Expand Down
28 changes: 28 additions & 0 deletions packages/core/test/tracing/timetodisplay.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { logger } from '@sentry/utils';
jest.spyOn(logger, 'warn');

import * as mockedtimetodisplaynative from './mockedtimetodisplaynative';
jest.mock('../../src/js/tracing/timetodisplaynative', () => mockedtimetodisplaynative);

import { isTurboModuleEnabled } from '../../src/js/utils/environment';
jest.mock('../../src/js/utils/environment', () => ({
isTurboModuleEnabled: jest.fn().mockReturnValue(false),
}));

import { getActiveSpan, getCurrentScope, getGlobalScope, getIsolationScope, getSpanDescendants, setCurrentClient, spanToJSON, startSpanManual} from '@sentry/core';
import type { Event, Measurements, Span, SpanJSON} from '@sentry/types';
import * as React from "react";
Expand Down Expand Up @@ -371,6 +379,26 @@ describe('TimeToDisplay', () => {
expect(spanToJSON(initialDisplaySpan!).timestamp).toEqual(initialDisplayEndTimestampMs / 1_000);
expect(spanToJSON(fullDisplaySpan!).timestamp).toEqual(fullDisplayEndTimestampMs / 1_000);
});

test('should not log a warning if native component exists and not in new architecture', async () => {

(isTurboModuleEnabled as jest.Mock).mockReturnValue(false);

TestRenderer.create(<TimeToInitialDisplay record={true} />);
await jest.runOnlyPendingTimersAsync(); // Flush setTimeout.

expect(logger.warn).not.toHaveBeenCalled();
});

test('should log a warning if in new architecture', async () => {

(isTurboModuleEnabled as jest.Mock).mockReturnValue(true);
TestRenderer.create(<TimeToInitialDisplay record={true} />);
await jest.runOnlyPendingTimersAsync(); // Flush setTimeout.

expect(logger.warn).toHaveBeenCalledWith(
'TimeToInitialDisplay and TimeToFullDisplay are not supported on the web, Expo Go and New Architecture. Run native build or report an issue at https://github.com/getsentry/sentry-react-native');
});
});

function getInitialDisplaySpan(span?: Span) {
Expand Down
Loading

0 comments on commit abcf737

Please sign in to comment.