React Native iOS does not report error causes (or multiple errors from an error array)
getsaf opened this issue · 2 comments
Describe the bug
package: @bugsnag/react-native
iOS does not report error causes (It works fine in Android).
Root cause is that the iOS event deserializer is hard-coded to only inspect/deserialize the first error that is reported
Additionally, I found that the bugsnag-cocoa
pod also hard-codes attachment of stack traces to the first error in the BugsnagEvent#errors
array in the attachCustomStacktrace function which is also called in the event deserializer here (this makes it difficult to provide a full solution without also making changes to bugsnag-cocoa
or duplicating some logic from bugsnag-cocoa
into the bugsnag-js
repo).
- (void)attachCustomStacktrace:(NSArray *)frames withType:(NSString *)type {
BugsnagError *error = self.errors.firstObject;
error.stacktrace = [BugsnagStacktrace stacktraceFromJson:frames].trace;
error.typeString = type;
}
Steps to reproduce
- Report an error with a cause property assigned
- View the report in the Bugsnag web UI
- See the cause is not reported
Environment
- Bugsnag version:
7.20.2
- Browser framework version (if any):
- n/a
- Server framework version (if any):
- n/a
- Device (e.g. iphonex):
- Any iPhone device
Example code snippet
const cause = new Error('This is the cause');
const error = new Error('This is the error', {cause});
bugsnag.notify(error);
My current solution is to apply this patch to the 7.20.2
version of the @bugsnag/react-native
package:
diff --git a/ios/BugsnagReactNative/BugsnagEventDeserializer.m b/ios/BugsnagReactNative/BugsnagEventDeserializer.m
index 280a788672eba80d678e790b427bc32c83c364e3..88a3c66a65dab7b64575982ebfe325863a7a7fa5 100644
--- a/ios/BugsnagReactNative/BugsnagEventDeserializer.m
+++ b/ios/BugsnagReactNative/BugsnagEventDeserializer.m
@@ -9,6 +9,8 @@
#import "BugsnagEventDeserializer.h"
#import "BugsnagInternals.h"
+#import "BugsnagError+Private.h"
+#import "BugsnagStacktrace.h"
@implementation BugsnagEventDeserializer
@@ -45,25 +47,31 @@ - (BugsnagEvent *)deserializeEvent:(NSDictionary *)payload {
}
}
- NSDictionary *error = payload[@"errors"][0];
-
- if (error != nil) {
- event.errors[0].errorClass = error[@"errorClass"];
- event.errors[0].errorMessage = error[@"errorMessage"];
- NSArray<NSDictionary *> *stacktrace = error[@"stacktrace"];
- NSArray<NSString *> *nativeStack = payload[@"nativeStack"];
- if (nativeStack) {
- NSMutableArray<NSDictionary *> *mixedStack = [NSMutableArray array];
- for (BugsnagStackframe *frame in [BugsnagStackframe stackframesWithCallStackSymbols:nativeStack]) {
- frame.type = BugsnagStackframeTypeCocoa;
- [frame symbolicateIfNeeded];
- [mixedStack addObject:[frame toDictionary]];
+ // Deserialize *all* errors instead of just the first one
+ // See issue: https://github.com/bugsnag/bugsnag-js/issues/1956
+ [payload[@"errors"] enumerateObjectsUsingBlock:^(NSDictionary *error, NSUInteger idx, BOOL *stop) {
+ if (error != nil) {
+ if (event.errors.count < idx + 1) {
+ event.errors = [event.errors arrayByAddingObject:[BugsnagError new]];
}
- [mixedStack addObjectsFromArray:stacktrace];
- stacktrace = mixedStack;
+ event.errors[idx].errorClass = error[@"errorClass"];
+ event.errors[idx].errorMessage = error[@"errorMessage"];
+ NSArray<NSDictionary *> *stacktrace = error[@"stacktrace"];
+ NSArray<NSString *> *nativeStack = payload[@"nativeStack"];
+ if (nativeStack) {
+ NSMutableArray<NSDictionary *> *mixedStack = [NSMutableArray array];
+ for (BugsnagStackframe *frame in [BugsnagStackframe stackframesWithCallStackSymbols:nativeStack]) {
+ frame.type = BugsnagStackframeTypeCocoa;
+ [frame symbolicateIfNeeded];
+ [mixedStack addObject:[frame toDictionary]];
+ }
+ [mixedStack addObjectsFromArray:stacktrace];
+ stacktrace = mixedStack;
+ }
+ event.errors[idx].stacktrace = [BugsnagStacktrace stacktraceFromJson:stacktrace].trace;
+ event.errors[idx].typeString = @"reactnativejs";
}
- [event attachCustomStacktrace:stacktrace withType:@"reactnativejs"];
- }
+ }];
return event;
}
Hi @getsaf, thanks for raising, we will look to get this fixed.