Skip to content

Commit 58b3261

Browse files
fix: Linked errors processed before other integrations (#3535)
1 parent 6cba1f1 commit 58b3261

File tree

14 files changed

+231
-126
lines changed

14 files changed

+231
-126
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
- Performance Tracing should be disabled by default ([#3533](https://github.com/getsentry/sentry-react-native/pull/3533))
3535
- Use `$NODE_BINARY` to execute Sentry CLI in Xcode scripts ([#3493](https://github.com/getsentry/sentry-react-native/pull/3493))
3636
- Return auto Release and Dist to source maps auto upload ([#3540](https://github.com/getsentry/sentry-react-native/pull/3540))
37+
- Linked errors processed before other integrations ([#3535](https://github.com/getsentry/sentry-react-native/pull/3535))
38+
- This ensure their frames are correctly symbolicated
3739

3840
### Dependencies
3941

android/src/main/java/io/sentry/react/RNSentryModuleImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,8 @@ public void fetchNativeSdkInfo(Promise promise) {
705705
}
706706
}
707707

708-
public void fetchNativePackageName(Promise promise) {
709-
promise.resolve(packageInfo.packageName);
708+
public String fetchNativePackageName() {
709+
return packageInfo.packageName;
710710
}
711711

712712
private void setEventOriginTag(SentryEvent event) {

android/src/newarch/java/io/sentry/react/RNSentryModule.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,13 @@ public WritableMap stopProfiling() {
135135
}
136136

137137
@Override
138-
public void fetchNativePackageName(Promise promise) {
139-
this.impl.fetchNativePackageName(promise);
138+
public String fetchNativePackageName() {
139+
return this.impl.fetchNativePackageName();
140140
}
141141

142142
@Override
143-
public void fetchNativeStackFramesBy(ReadableArray instructionsAddr, Promise promise) {
143+
public WritableMap fetchNativeStackFramesBy(ReadableArray instructionsAddr) {
144144
// Not used on Android
145+
return null;
145146
}
146147
}

android/src/oldarch/java/io/sentry/react/RNSentryModule.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,14 @@ public WritableMap stopProfiling() {
133133
return this.impl.stopProfiling();
134134
}
135135

136-
@ReactMethod
137-
public void fetchNativePackageName(Promise promise) {
138-
this.impl.fetchNativePackageName(promise);
136+
@ReactMethod(isBlockingSynchronousMethod = true)
137+
public String fetchNativePackageName() {
138+
return this.impl.fetchNativePackageName();
139139
}
140140

141-
@ReactMethod
142-
public void fetchNativeStackFramesBy(ReadableArray instructionsAddr, Promise promise) {
141+
@ReactMethod(isBlockingSynchronousMethod = true)
142+
public WritableMap fetchNativeStackFramesBy(ReadableArray instructionsAddr) {
143143
// Not used on Android
144+
return null;
144145
}
145146
}

ios/RNSentry.mm

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,10 @@ - (void)setEventEnvironmentTag:(SentryEvent *)event
201201
resolve(modulesString);
202202
}
203203

204-
RCT_EXPORT_METHOD(fetchNativePackageName:(RCTPromiseResolveBlock)resolve
205-
rejecter:(RCTPromiseRejectBlock)reject)
204+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, fetchNativePackageName)
206205
{
207206
NSString *packageName = [[NSBundle mainBundle] executablePath];
208-
resolve(packageName);
207+
return packageName;
209208
}
210209

211210
- (NSDictionary*) fetchNativeStackFramesBy: (NSArray<NSNumber*>*)instructionsAddr
@@ -273,12 +272,10 @@ - (NSDictionary*) fetchNativeStackFramesBy: (NSArray<NSNumber*>*)instructionsAdd
273272
}
274273
}
275274

276-
RCT_EXPORT_METHOD(fetchNativeStackFramesBy:(NSArray *)instructionsAddr
277-
resolve:(RCTPromiseResolveBlock)resolve
278-
reject:(RCTPromiseRejectBlock)reject)
275+
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, fetchNativeStackFramesBy:(NSArray *)instructionsAddr)
279276
{
280-
resolve([self fetchNativeStackFramesBy:instructionsAddr
281-
symbolicate:dladdr]);
277+
return [self fetchNativeStackFramesBy:instructionsAddr
278+
symbolicate:dladdr];
282279
}
283280

284281
RCT_EXPORT_METHOD(fetchNativeDeviceContexts:(RCTPromiseResolveBlock)resolve

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = {
22
collectCoverage: true,
33
preset: 'react-native',
4-
setupFilesAfterEnv: ['<rootDir>/test/mockConsole.ts'],
4+
setupFilesAfterEnv: ['jest-extended/all', '<rootDir>/test/mockConsole.ts'],
55
globals: {
66
__DEV__: true,
77
'ts-jest': {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"expo-module-scripts": "^3.1.0",
9797
"jest": "^29.6.2",
9898
"jest-environment-jsdom": "^29.6.2",
99+
"jest-extended": "^4.0.2",
99100
"madge": "^6.1.0",
100101
"metro": "0.76",
101102
"prettier": "^2.0.5",

src/js/NativeRNSentry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ export interface Spec extends TurboModule {
3434
fetchViewHierarchy(): Promise<number[] | undefined | null>;
3535
startProfiling(): { started?: boolean; error?: string };
3636
stopProfiling(): { profile?: string; nativeProfile?: UnsafeObject; error?: string };
37-
fetchNativePackageName(): Promise<string | undefined | null>;
38-
fetchNativeStackFramesBy(instructionsAddr: number[]): Promise<NativeStackFrames | undefined | null>;
37+
fetchNativePackageName(): string | undefined | null;
38+
fetchNativeStackFramesBy(instructionsAddr: number[]): NativeStackFrames | undefined | null;
3939
}
4040

4141
export type NativeStackFrame = {

src/js/integrations/nativelinkederrors.ts

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { exceptionFromError } from '@sentry/browser';
22
import type {
3+
Client,
34
DebugImage,
45
Event,
56
EventHint,
@@ -53,35 +54,29 @@ export class NativeLinkedErrors implements Integration {
5354
/**
5455
* @inheritDoc
5556
*/
56-
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
57-
const client = getCurrentHub().getClient();
58-
if (!client) {
59-
return;
57+
public setupOnce(_addGlobalEventProcessor: (callback: EventProcessor) => void, _getCurrentHub: () => Hub): void {
58+
/* noop */
59+
}
60+
61+
/**
62+
* @inheritDoc
63+
*/
64+
public preprocessEvent(event: Event, hint: EventHint | undefined, client: Client): void {
65+
if (this._nativePackage === null) {
66+
this._nativePackage = this._fetchNativePackage();
6067
}
6168

62-
addGlobalEventProcessor(async (event: Event, hint?: EventHint) => {
63-
if (this._nativePackage === null) {
64-
this._nativePackage = await this._fetchNativePackage();
65-
}
66-
const self = getCurrentHub().getIntegration(NativeLinkedErrors);
67-
return self ? this._handler(client.getOptions().stackParser, self._key, self._limit, event, hint) : event;
68-
});
69+
this._handler(client.getOptions().stackParser, this._key, this._limit, event, hint);
6970
}
7071

7172
/**
7273
* Enriches passed event with linked exceptions and native debug meta images.
7374
*/
74-
private async _handler(
75-
parser: StackParser,
76-
key: string,
77-
limit: number,
78-
event: Event,
79-
hint?: EventHint,
80-
): Promise<Event | null> {
75+
private _handler(parser: StackParser, key: string, limit: number, event: Event, hint?: EventHint): void {
8176
if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
82-
return event;
77+
return;
8378
}
84-
const { exceptions: linkedErrors, debugImages } = await this._walkErrorTree(
79+
const { exceptions: linkedErrors, debugImages } = this._walkErrorTree(
8580
parser,
8681
limit,
8782
hint.originalException as ExtendedError,
@@ -92,25 +87,23 @@ export class NativeLinkedErrors implements Integration {
9287
event.debug_meta = event.debug_meta || {};
9388
event.debug_meta.images = event.debug_meta.images || [];
9489
event.debug_meta.images.push(...(debugImages || []));
95-
96-
return event;
9790
}
9891

9992
/**
10093
* Walks linked errors and created Sentry exceptions chain.
10194
* Collects debug images from native errors stack frames.
10295
*/
103-
private async _walkErrorTree(
96+
private _walkErrorTree(
10497
parser: StackParser,
10598
limit: number,
10699
error: ExtendedError,
107100
key: string,
108101
exceptions: Exception[] = [],
109102
debugImages: DebugImage[] = [],
110-
): Promise<{
103+
): {
111104
exceptions: Exception[];
112105
debugImages?: DebugImage[];
113-
}> {
106+
} {
114107
const linkedError = error[key];
115108
if (!linkedError || exceptions.length + 1 >= limit) {
116109
return {
@@ -126,7 +119,7 @@ export class NativeLinkedErrors implements Integration {
126119
exception = this._exceptionFromJavaStackElements(linkedError);
127120
} else if ('stackReturnAddresses' in linkedError) {
128121
// isObjCException
129-
const { appleException, appleDebugImages } = await this._exceptionFromAppleStackReturnAddresses(linkedError);
122+
const { appleException, appleDebugImages } = this._exceptionFromAppleStackReturnAddresses(linkedError);
130123
exception = appleException;
131124
exceptionDebugImages = appleDebugImages;
132125
} else if (isInstanceOf(linkedError, Error)) {
@@ -193,15 +186,15 @@ export class NativeLinkedErrors implements Integration {
193186
/**
194187
* Converts StackAddresses to a SentryException with DebugMetaImages
195188
*/
196-
private async _exceptionFromAppleStackReturnAddresses(objCException: {
189+
private _exceptionFromAppleStackReturnAddresses(objCException: {
197190
name: string;
198191
message: string;
199192
stackReturnAddresses: number[];
200-
}): Promise<{
193+
}): {
201194
appleException: Exception;
202195
appleDebugImages: DebugImage[];
203-
}> {
204-
const nativeStackFrames = await this._fetchNativeStackFrames(objCException.stackReturnAddresses);
196+
} {
197+
const nativeStackFrames = this._fetchNativeStackFrames(objCException.stackReturnAddresses);
205198

206199
return {
207200
appleException: {
@@ -218,14 +211,14 @@ export class NativeLinkedErrors implements Integration {
218211
/**
219212
* Fetches the native package/image name from the native layer
220213
*/
221-
private _fetchNativePackage(): Promise<string | null> {
214+
private _fetchNativePackage(): string | null {
222215
return NATIVE.fetchNativePackageName();
223216
}
224217

225218
/**
226219
* Fetches native debug image information on iOS
227220
*/
228-
private _fetchNativeStackFrames(instructionsAddr: number[]): Promise<NativeStackFrames | null> {
221+
private _fetchNativeStackFrames(instructionsAddr: number[]): NativeStackFrames | null {
229222
return NATIVE.fetchNativeStackFramesBy(instructionsAddr);
230223
}
231224
}

src/js/wrapper.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ interface SentryNativeWrapper {
8585
startProfiling(): boolean;
8686
stopProfiling(): { hermesProfile: Hermes.Profile; nativeProfile?: NativeProfileEvent } | null;
8787

88-
fetchNativePackageName(): Promise<string | null>;
88+
fetchNativePackageName(): string | null;
8989

9090
/**
9191
* Fetches native stack frames and debug images for the instructions addresses.
9292
*/
93-
fetchNativeStackFramesBy(instructionsAddr: number[]): Promise<NativeStackFrames | null>;
93+
fetchNativeStackFramesBy(instructionsAddr: number[]): NativeStackFrames | null;
9494
}
9595

9696
const EOL = utf8ToBytes('\n');
@@ -554,26 +554,26 @@ export const NATIVE: SentryNativeWrapper = {
554554
}
555555
},
556556

557-
async fetchNativePackageName(): Promise<string | null> {
557+
fetchNativePackageName(): string | null {
558558
if (!this.enableNative) {
559559
return null;
560560
}
561561
if (!this._isModuleLoaded(RNSentry)) {
562562
return null;
563563
}
564564

565-
return (await RNSentry.fetchNativePackageName()) || null;
565+
return RNSentry.fetchNativePackageName() || null;
566566
},
567567

568-
async fetchNativeStackFramesBy(instructionsAddr: number[]): Promise<NativeStackFrames | null> {
568+
fetchNativeStackFramesBy(instructionsAddr: number[]): NativeStackFrames | null {
569569
if (!this.enableNative) {
570570
return null;
571571
}
572572
if (!this._isModuleLoaded(RNSentry)) {
573573
return null;
574574
}
575575

576-
return (await RNSentry.fetchNativeStackFramesBy(instructionsAddr)) || null;
576+
return RNSentry.fetchNativeStackFramesBy(instructionsAddr) || null;
577577
},
578578

579579
/**

0 commit comments

Comments
 (0)