Skip to content

Commit 1728356

Browse files
committed
Merge branch 'main' into feedback-ui-2
# Conflicts: # CHANGELOG.md # samples/react-native/src/App.tsx
2 parents 92c4d2d + 834729f commit 1728356

File tree

14 files changed

+248
-90
lines changed

14 files changed

+248
-90
lines changed

CHANGELOG.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,32 @@
1111
### Features
1212

1313
- Adds the `FeedbackButton` component that shows the Feedback Widget ([#4378](https://github.com/getsentry/sentry-react-native/pull/4378))
14-
- Add Feedback Widget theming ([#4677](https://github.com/getsentry/sentry-react-native/pull/4677))
1514
- Adds the `ScreenshotButton` component that takes a screenshot ([#4714](https://github.com/getsentry/sentry-react-native/issues/4714))
15+
- Add Feedback Widget theming ([#4677](https://github.com/getsentry/sentry-react-native/pull/4677))
1616

1717
### Fixes
1818

1919
- Expo Updates Context is passed to native after native init to be available for crashes ([#4808](https://github.com/getsentry/sentry-react-native/pull/4808))
20+
- Expo Updates Context values should all be lowercase ([#4809](https://github.com/getsentry/sentry-react-native/pull/4809))
2021
- Fixes Feedback Widget accessibility issue on iOS ([#4739](https://github.com/getsentry/sentry-react-native/pull/4739))
2122

2223
### Dependencies
2324

24-
- Bump CLI from v2.43.1 to v2.44.0 ([#4804](https://github.com/getsentry/sentry-react-native/pull/4804))
25-
- [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#2440)
26-
- [diff](https://github.com/getsentry/sentry-cli/compare/2.43.1...2.44.0)
25+
- Bump CLI from v2.43.1 to v2.45.0 ([#4804](https://github.com/getsentry/sentry-react-native/pull/4804), [#4818](https://github.com/getsentry/sentry-react-native/pull/4818))
26+
- [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#2450)
27+
- [diff](https://github.com/getsentry/sentry-cli/compare/2.43.1...2.45.0)
2728
- Bump Bundler Plugins from v3.3.1 to v3.4.0 ([#4805](https://github.com/getsentry/sentry-react-native/pull/4805))
2829
- [changelog](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/CHANGELOG.md#340)
2930
- [diff](https://github.com/getsentry/sentry-javascript-bundler-plugins/compare/3.3.1...3.4.0)
3031
- Bump Cocoa SDK from v8.49.2 to v8.50.0 ([#4807](https://github.com/getsentry/sentry-react-native/pull/4807))
3132
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8500)
3233
- [diff](https://github.com/getsentry/sentry-cocoa/compare/8.49.2...8.50.0)
3334

35+
### Fixes
36+
37+
- Avoid duplicate network requests (fetch, xhr) by default ([#4816](https://github.com/getsentry/sentry-react-native/pull/4816))
38+
- `traceFetch` is disabled by default on mobile as RN uses a polyfill which will be traced by `traceXHR`
39+
3440
## 6.13.1
3541

3642
### Fixes

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"devDependencies": {
3131
"@expo/swiftlint": "^0.57.1",
3232
"@naturalcycles/ktlint": "^1.13.0",
33-
"@sentry/cli": "2.44.0",
33+
"@sentry/cli": "2.45.0",
3434
"clang-format": "^1.8.0",
3535
"downlevel-dts": "^0.11.0",
3636
"google-java-format": "^1.4.0",

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"dependencies": {
6868
"@sentry/babel-plugin-component-annotate": "3.4.0",
6969
"@sentry/browser": "8.54.0",
70-
"@sentry/cli": "2.44.0",
70+
"@sentry/cli": "2.45.0",
7171
"@sentry/core": "8.54.0",
7272
"@sentry/react": "8.54.0",
7373
"@sentry/types": "8.54.0",

packages/core/src/js/integrations/expocontext.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ export const expoContextIntegration = (): Integration => {
7070
};
7171
};
7272

73-
function getExpoUpdatesContext(): ExpoUpdatesContext {
73+
/**
74+
* @internal Exposed for testing purposes
75+
*/
76+
export function getExpoUpdatesContext(): ExpoUpdatesContext {
7477
const expoUpdates = getExpoUpdates();
7578
if (!expoUpdates) {
7679
return {
@@ -85,19 +88,19 @@ function getExpoUpdatesContext(): ExpoUpdatesContext {
8588
is_using_embedded_assets: !!expoUpdates.isUsingEmbeddedAssets,
8689
};
8790

88-
if (typeof expoUpdates.updateId === 'string') {
89-
updatesContext.update_id = expoUpdates.updateId;
91+
if (typeof expoUpdates.updateId === 'string' && expoUpdates.updateId) {
92+
updatesContext.update_id = expoUpdates.updateId.toLowerCase();
9093
}
91-
if (typeof expoUpdates.channel === 'string') {
92-
updatesContext.channel = expoUpdates.channel;
94+
if (typeof expoUpdates.channel === 'string' && expoUpdates.channel) {
95+
updatesContext.channel = expoUpdates.channel.toLowerCase();
9396
}
94-
if (typeof expoUpdates.runtimeVersion === 'string') {
95-
updatesContext.runtime_version = expoUpdates.runtimeVersion;
97+
if (typeof expoUpdates.runtimeVersion === 'string' && expoUpdates.runtimeVersion) {
98+
updatesContext.runtime_version = expoUpdates.runtimeVersion.toLowerCase();
9699
}
97-
if (typeof expoUpdates.checkAutomatically === 'string') {
98-
updatesContext.check_automatically = expoUpdates.checkAutomatically;
100+
if (typeof expoUpdates.checkAutomatically === 'string' && expoUpdates.checkAutomatically) {
101+
updatesContext.check_automatically = expoUpdates.checkAutomatically.toLowerCase();
99102
}
100-
if (typeof expoUpdates.emergencyLaunchReason === 'string') {
103+
if (typeof expoUpdates.emergencyLaunchReason === 'string' && expoUpdates.emergencyLaunchReason) {
101104
updatesContext.emergency_launch_reason = expoUpdates.emergencyLaunchReason;
102105
}
103106
if (typeof expoUpdates.launchDuration === 'number') {

packages/core/src/js/tracing/reactnativetracing.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ export interface ReactNativeTracingOptions {
2929
/**
3030
* Flag to disable patching all together for fetch requests.
3131
*
32-
* @default true
32+
* Fetch in React Native is a `whatwg-fetch` polyfill which uses XHR under the hood.
33+
* This causes duplicates when both `traceFetch` and `traceXHR` are enabled at the same time.
34+
*
35+
* @default false
3336
*/
3437
traceFetch: boolean;
3538

@@ -70,7 +73,11 @@ function getDefaultTracePropagationTargets(): RegExp[] | undefined {
7073
}
7174

7275
export const defaultReactNativeTracingOptions: ReactNativeTracingOptions = {
73-
traceFetch: true,
76+
// Fetch in React Native is a `whatwg-fetch` polyfill which uses XHR under the hood.
77+
// This causes duplicates when both `traceFetch` and `traceXHR` are enabled at the same time.
78+
// https://github.com/facebook/react-native/blob/28945c68da056ab2ac01de7e542a845b2bca6096/packages/react-native/Libraries/Network/fetch.js
79+
// (RN Web uses browsers native fetch implementation)
80+
traceFetch: isWeb() ? true : false,
7481
traceXHR: true,
7582
enableHTTPTimings: true,
7683
};

packages/core/test/integrations/expocontext.test.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { type Client, type Event, getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';
22

3-
import { expoContextIntegration, OTA_UPDATES_CONTEXT_KEY } from '../../src/js/integrations/expocontext';
3+
import {
4+
expoContextIntegration,
5+
getExpoUpdatesContext,
6+
OTA_UPDATES_CONTEXT_KEY,
7+
} from '../../src/js/integrations/expocontext';
48
import * as environment from '../../src/js/utils/environment';
59
import type { ExpoUpdates } from '../../src/js/utils/expoglobalobject';
610
import { getExpoDevice } from '../../src/js/utils/expomodules';
@@ -311,6 +315,59 @@ describe('Expo Context Integration', () => {
311315
});
312316
});
313317

318+
describe('getExpoUpdatesContext', () => {
319+
it('does not return empty values', () => {
320+
jest.spyOn(expoModules, 'getExpoUpdates').mockReturnValue({
321+
isEnabled: false,
322+
isEmbeddedLaunch: false,
323+
isEmergencyLaunch: false,
324+
isUsingEmbeddedAssets: false,
325+
updateId: '',
326+
channel: '',
327+
runtimeVersion: '',
328+
checkAutomatically: '',
329+
emergencyLaunchReason: '',
330+
launchDuration: 0,
331+
createdAt: new Date('2021-01-01T00:00:00.000Z'),
332+
});
333+
334+
const expoUpdates = getExpoUpdatesContext();
335+
336+
expect(expoUpdates).toStrictEqual({
337+
is_enabled: false,
338+
is_embedded_launch: false,
339+
is_emergency_launch: false,
340+
is_using_embedded_assets: false,
341+
launch_duration: 0,
342+
created_at: '2021-01-01T00:00:00.000Z',
343+
});
344+
});
345+
346+
it('lowercases all string values', () => {
347+
jest.spyOn(expoModules, 'getExpoUpdates').mockReturnValue({
348+
updateId: 'UPPERCASE-123',
349+
channel: 'UPPERCASE-123',
350+
runtimeVersion: 'UPPERCASE-123',
351+
checkAutomatically: 'UPPERCASE-123',
352+
emergencyLaunchReason: 'This is a description of the reason.',
353+
createdAt: new Date('2021-01-01T00:00:00.000Z'),
354+
});
355+
356+
const expoUpdates = getExpoUpdatesContext();
357+
358+
expect(expoUpdates).toEqual(
359+
expect.objectContaining({
360+
update_id: 'uppercase-123',
361+
channel: 'uppercase-123',
362+
runtime_version: 'uppercase-123',
363+
check_automatically: 'uppercase-123',
364+
emergency_launch_reason: 'This is a description of the reason.', // Description should be kept as is
365+
created_at: '2021-01-01T00:00:00.000Z', // Date should keep ISO string format
366+
}),
367+
);
368+
});
369+
});
370+
314371
function executeIntegrationFor(mockedEvent: Event): Event {
315372
return expoContextIntegration().processEvent!(mockedEvent, {}, {} as Client) as Event;
316373
}

packages/core/test/tracing/timetodisplay.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jest.mock('../../src/js/tracing/timetodisplaynative', () => mockedtimetodisplayn
99

1010
import { isTurboModuleEnabled } from '../../src/js/utils/environment';
1111
jest.mock('../../src/js/utils/environment', () => ({
12+
isWeb: jest.fn().mockReturnValue(false),
1213
isTurboModuleEnabled: jest.fn().mockReturnValue(false),
1314
}));
1415

samples/expo/app/(tabs)/index.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { Button, StyleSheet } from 'react-native';
22
import Constants from 'expo-constants';
33
import * as Sentry from '@sentry/react-native';
44
import { reloadAppAsync } from 'expo';
5+
import * as DevClient from 'expo-dev-client';
56

67
import { Text, View } from '@/components/Themed';
78
import { setScopeProperties } from '@/utils/setScopeProperties';
89
import React from 'react';
910
import * as WebBrowser from 'expo-web-browser';
1011
import { useUpdates } from 'expo-updates';
12+
import { isWeb } from '../../utils/isWeb';
1113

12-
const isRunningInExpoGo = Constants.appOwnership === 'expo'
14+
const isRunningInExpoGo = Constants.appOwnership === 'expo';
1315

1416
export default function TabOneScreen() {
1517
const { currentlyRunning } = useUpdates();
@@ -20,6 +22,13 @@ export default function TabOneScreen() {
2022
<Text>Update ID: {currentlyRunning.updateId}</Text>
2123
<Text>Channel: {currentlyRunning.channel}</Text>
2224
<Text>Runtime Version: {currentlyRunning.runtimeVersion}</Text>
25+
<Button
26+
title="Open DevMenu"
27+
onPress={() => {
28+
DevClient.openMenu();
29+
}}
30+
disabled={isWeb()}
31+
/>
2332
<Button
2433
title="Capture message"
2534
onPress={() => {
@@ -35,8 +44,8 @@ export default function TabOneScreen() {
3544
<Button
3645
title="Capture exception with cause"
3746
onPress={() => {
38-
const error = new Error('Captured exception')
39-
error.cause = new Error('Cause of captured exception')
47+
const error = new Error('Captured exception');
48+
error.cause = new Error('Cause of captured exception');
4049
Sentry.captureException(error);
4150
}}
4251
/>

samples/expo/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@types/react": "~19.0.10",
2222
"expo": "^53.0.0",
2323
"expo-constants": "~17.1.5",
24+
"expo-dev-client": "~5.1.8",
2425
"expo-image-picker": "~16.1.4",
2526
"expo-linking": "~7.1.4",
2627
"expo-router": "~5.0.5",

samples/react-native/e2e/captureSpaceflightNewsScreenTransaction.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,19 @@ describe('Capture Spaceflight News Screen Transaction', () => {
108108
}),
109109
);
110110
});
111+
112+
it('contains exactly two articles requests spans', () => {
113+
// This test ensures we are to tracing requests multiple times on different layers
114+
// fetch > xhr > native
115+
116+
const item = getFirstNewsEventItem();
117+
const spans = item?.[1].spans;
118+
119+
console.log(spans);
120+
121+
const httpSpans = spans?.filter(
122+
span => span.data?.['sentry.op'] === 'http.client',
123+
);
124+
expect(httpSpans).toHaveLength(2);
125+
});
111126
});

0 commit comments

Comments
 (0)