Skip to content

Commit 312116d

Browse files
committed
Merge branch 'main' into feedback-ui
2 parents aa15c88 + 4161236 commit 312116d

File tree

5 files changed

+75
-25
lines changed

5 files changed

+75
-25
lines changed

.github/workflows/e2e.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,15 @@ jobs:
162162
strategy:
163163
fail-fast: false # keeps matrix running if one fails
164164
matrix:
165-
rn-version: ['0.65.3', '0.76.0']
165+
rn-version: ['0.65.3', '0.76.6']
166166
rn-architecture: ['legacy', 'new']
167167
platform: ['android', 'ios']
168168
build-type: ['production']
169169
ios-use-frameworks: ['no', 'static', 'dynamic']
170170
engine: ['hermes', 'jsc']
171171
include:
172172
- platform: ios
173-
rn-version: '0.76.0'
173+
rn-version: '0.76.6'
174174
runs-on: macos-14
175175
- platform: ios
176176
rn-version: '0.65.3'
@@ -179,7 +179,7 @@ jobs:
179179
runs-on: ubuntu-latest
180180
exclude:
181181
# exclude JSC for new RN versions (keeping the matrix manageable)
182-
- rn-version: '0.76.0'
182+
- rn-version: '0.76.6'
183183
engine: 'jsc'
184184
# exclude all rn versions lower than 0.70.0 for new architecture
185185
- rn-version: '0.65.3'
@@ -298,15 +298,15 @@ jobs:
298298
strategy:
299299
fail-fast: false # keeps matrix running if one fails
300300
matrix:
301-
rn-version: ['0.65.3', '0.76.0']
301+
rn-version: ['0.65.3', '0.76.6']
302302
rn-architecture: ['legacy', 'new']
303303
platform: ['android', 'ios']
304304
build-type: ['production']
305305
ios-use-frameworks: ['no'] # test only no framworks
306306
engine: ['hermes', 'jsc']
307307
include:
308308
- platform: ios
309-
rn-version: '0.76.0'
309+
rn-version: '0.76.6'
310310
runs-on: macos-15
311311
- platform: ios
312312
rn-version: '0.65.3'
@@ -320,7 +320,7 @@ jobs:
320320
# e2e test only the default combinations
321321
- rn-version: '0.65.3'
322322
engine: 'hermes'
323-
- rn-version: '0.76.0'
323+
- rn-version: '0.76.6'
324324
engine: 'jsc'
325325

326326
steps:

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@
2323
### Fixes
2424

2525
- Use proper SDK name for Session Replay tags ([#4428](https://github.com/getsentry/sentry-react-native/pull/4428))
26+
- Use `makeDsn` from `core` to extract the URL from DSN avoiding unimplemented `URL.protocol` errors ([#4395](https://github.com/getsentry/sentry-react-native/pull/4395))
2627

2728
### Changes
2829

2930
- Rename `navigation.processing` span to more expressive `Navigation dispatch to screen A mounted/navigation cancelled` ([#4423](https://github.com/getsentry/sentry-react-native/pull/4423))
3031
- Add RN SDK package to `sdk.packages` for Cocoa ([#4381](https://github.com/getsentry/sentry-react-native/pull/4381))
3132

33+
### Internal
34+
35+
- Initialize `RNSentryTimeToDisplay` during native module `init` on iOS ([#4443](https://github.com/getsentry/sentry-react-native/pull/4443))
36+
3237
### Dependencies
3338

3439
- Bump CLI from v2.39.1 to v2.40.0 ([#4412](https://github.com/getsentry/sentry-react-native/pull/4412))

packages/core/ios/RNSentry.mm

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ + (BOOL)requiresMainQueueSetup
7878
return YES;
7979
}
8080

81+
- (instancetype)init
82+
{
83+
if (self = [super init]) {
84+
_timeToDisplay = [[RNSentryTimeToDisplay alloc] init];
85+
}
86+
return self;
87+
}
88+
8189
RCT_EXPORT_MODULE()
8290

8391
RCT_EXPORT_METHOD(initNativeSdk
@@ -152,8 +160,6 @@ - (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)
152160
[mutableOptions removeObjectForKey:@"tracesSampler"];
153161
[mutableOptions removeObjectForKey:@"enableTracing"];
154162

155-
_timeToDisplay = [[RNSentryTimeToDisplay alloc] init];
156-
157163
#if SENTRY_TARGET_REPLAY_SUPPORTED
158164
[RNSentryReplay updateOptions:mutableOptions];
159165
#endif

packages/core/src/js/sdk.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable complexity */
22
import type { Breadcrumb, BreadcrumbHint, Integration, Scope, SendFeedbackParams, UserFeedback } from '@sentry/core';
3-
import { captureFeedback, getClient, getGlobalScope, getIntegrationsToSetup, getIsolationScope, initAndBind, logger, stackParserFromStackParserOptions, withScope as coreWithScope } from '@sentry/core';
3+
import { captureFeedback, getClient, getGlobalScope, getIntegrationsToSetup, getIsolationScope, initAndBind, logger, makeDsn, stackParserFromStackParserOptions, withScope as coreWithScope } from '@sentry/core';
44
import {
55
defaultStackParser,
66
makeFetchTransport,
@@ -66,13 +66,13 @@ export function init(passedOptions: ReactNativeOptions): void {
6666
if (!dsn) {
6767
return undefined;
6868
}
69-
try {
70-
const url = new URL(dsn);
71-
return `${url.protocol}//${url.host}`;
72-
} catch (e) {
73-
logger.error('Failed to extract url from DSN', e);
69+
const dsnComponents = makeDsn(dsn);
70+
if (!dsnComponents) {
71+
logger.error('Failed to extract url from DSN: ', dsn);
7472
return undefined;
7573
}
74+
const port = dsnComponents.port ? `:${dsnComponents.port}` : '';
75+
return `${dsnComponents.protocol}://${dsnComponents.host}${port}`;
7676
};
7777

7878
const userBeforeBreadcrumb = safeFactory(passedOptions.beforeBreadcrumb, { loggerMessage: 'The beforeBreadcrumb threw an error' });

packages/core/test/sdk.test.ts

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ describe('Tests the SDK functionality', () => {
321321
expect(result).toBeNull();
322322
});
323323

324-
it('should filters out dsn breadcrumbs', () => {
324+
it('should filter out dsn breadcrumbs', () => {
325325
(getDevServer as jest.Mock).mockReturnValue({ url: 'http://localhost:8081' });
326326

327327
const mockBeforeBreadcrumb = (breadcrumb: Breadcrumb, _hint?: BreadcrumbHint) => {
@@ -345,37 +345,76 @@ describe('Tests the SDK functionality', () => {
345345
expect(result).toBeNull();
346346
});
347347

348-
it('should keep breadcrumbs matching dsn if the url parsing fails for dsn', () => {
348+
it('should filter out dsn breadcrumbs that the ports match', () => {
349349
(getDevServer as jest.Mock).mockReturnValue({ url: 'http://localhost:8081' });
350350

351351
const mockBeforeBreadcrumb = (breadcrumb: Breadcrumb, _hint?: BreadcrumbHint) => {
352352
return breadcrumb;
353353
};
354354

355-
// Mock the URL constructor to throw an exception for this test case
356-
const originalURL = (global as any).URL;
357-
jest.spyOn(global as any, 'URL').mockImplementationOnce(() => {
358-
throw new Error('Failed to parse DSN URL');
359-
});
355+
const passedOptions = {
356+
dsn: 'https://[email protected]:8181/1234567',
357+
beforeBreadcrumb: mockBeforeBreadcrumb,
358+
};
359+
360+
init(passedOptions);
361+
362+
const breadcrumb: Breadcrumb = {
363+
type: 'http',
364+
data: { url: 'https://selfhosted.app.server:8181/api' },
365+
};
366+
367+
const result = usedOptions()?.beforeBreadcrumb!(breadcrumb);
368+
369+
expect(result).toBeNull();
370+
});
371+
372+
it('should keep breadcrumbs if the ports do not match', () => {
373+
(getDevServer as jest.Mock).mockReturnValue({ url: 'http://localhost:8081' });
374+
375+
const mockBeforeBreadcrumb = (breadcrumb: Breadcrumb, _hint?: BreadcrumbHint) => {
376+
return breadcrumb;
377+
};
360378

361379
const passedOptions = {
362-
dsn: 'https://[email protected]/1234567',
380+
dsn: 'https://[email protected]:8181/1234567',
363381
beforeBreadcrumb: mockBeforeBreadcrumb,
364382
};
365383

366384
init(passedOptions);
367385

368386
const breadcrumb: Breadcrumb = {
369387
type: 'http',
370-
data: { url: 'https://def.ingest.sentry.io/1234567' },
388+
data: { url: 'https://selfhosted.app.server:8080/api' },
371389
};
372390

373391
const result = usedOptions()?.beforeBreadcrumb!(breadcrumb);
374392

375393
expect(result).toEqual(breadcrumb);
394+
});
395+
396+
it('should keep breadcrumbs if the url parsing fails for dsn', () => {
397+
(getDevServer as jest.Mock).mockReturnValue({ url: 'http://localhost:8081' });
398+
399+
const mockBeforeBreadcrumb = (breadcrumb: Breadcrumb, _hint?: BreadcrumbHint) => {
400+
return breadcrumb;
401+
};
402+
403+
const passedOptions = {
404+
dsn: 'invalid-dsn',
405+
beforeBreadcrumb: mockBeforeBreadcrumb,
406+
};
407+
408+
init(passedOptions);
376409

377-
// Restore the original URL constructor
378-
(global as any).URL = originalURL;
410+
const breadcrumb: Breadcrumb = {
411+
type: 'http',
412+
data: { url: 'https://def.ingest.sentry.io/1234567' },
413+
};
414+
415+
const result = usedOptions()?.beforeBreadcrumb!(breadcrumb);
416+
417+
expect(result).toEqual(breadcrumb);
379418
});
380419

381420
it('should keep non dev server or dsn breadcrumbs', () => {

0 commit comments

Comments
 (0)