Skip to content

Commit

Permalink
feat: Add in_foreground AppContext to crash events (#4584)
Browse files Browse the repository at this point in the history
The SDK now adds the in_foreground AppContext to crash events by
retrieving this information from the application_stats of the crash
report.

Fixes GH-4563
  • Loading branch information
philipphofmann authored Nov 29, 2024
1 parent 0f87fe3 commit 0aa3e78
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Features

- Add in_foreground app context to transactions (#4561)
- Add in_foreground app context to crash events ((#4584)
- Promote the option `performanceV2` from experimental to stable (#4564)

### Fixes
Expand Down
16 changes: 14 additions & 2 deletions Sources/Sentry/SentryCrashReportConverter.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ @interface SentryCrashReportConverter ()
@property (nonatomic, strong) NSArray *binaryImages;
@property (nonatomic, strong) NSArray *threads;
@property (nonatomic, strong) NSDictionary *systemContext;
@property (nonatomic, strong) NSDictionary *applicationStats;
@property (nonatomic, strong) NSString *diagnosis;
@property (nonatomic, strong) SentryInAppLogic *inAppLogic;

Expand All @@ -38,7 +39,6 @@ - (instancetype)initWithReport:(NSDictionary *)report inAppLogic:(SentryInAppLog
if (self) {
self.report = report;
self.inAppLogic = inAppLogic;
self.systemContext = report[@"system"];

NSDictionary *userContextUnMerged = report[@"user"];
if (userContextUnMerged == nil) {
Expand Down Expand Up @@ -72,6 +72,11 @@ - (instancetype)initWithReport:(NSDictionary *)report inAppLogic:(SentryInAppLog
self.diagnosis = crashContext[@"diagnosis"];
self.exceptionContext = crashContext[@"error"];
[self initThreads:crashContext[@"threads"]];

self.systemContext = report[@"system"];
if (self.systemContext[@"application_stats"] != nil) {
self.applicationStats = self.systemContext[@"application_stats"];
}
}
return self;
}
Expand Down Expand Up @@ -119,6 +124,14 @@ - (SentryEvent *_Nullable)convertReportToEvent
mutableContext[@"trace"] = self.userContext[@"traceContext"];
}

NSMutableDictionary *appContext;
if (mutableContext[@"app"] != nil) {
appContext = [mutableContext[@"app"] mutableCopy];
} else {
appContext = [NSMutableDictionary new];
}
appContext[@"in_foreground"] = self.applicationStats[@"application_in_foreground"];
mutableContext[@"app"] = appContext;
event.context = mutableContext;

event.extra = self.userContext[@"extra"];
Expand All @@ -135,7 +148,6 @@ - (SentryEvent *_Nullable)convertReportToEvent
// We want to set the release and dist to the version from the crash report
// itself otherwise it can happend that we have two different version when
// the app crashes right before an app update #218 #219
NSDictionary *appContext = event.context[@"app"];
if (nil == event.releaseName && appContext[@"app_identifier"] && appContext[@"app_version"]
&& appContext[@"app_build"]) {
event.releaseName =
Expand Down
58 changes: 57 additions & 1 deletion Tests/SentryTests/SentryKSCrashReportConverterTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,68 @@ - (void)testTraceContext
SentryEvent *event = [reportConverter convertReportToEvent];
NSDictionary *expectedContext = @{
@"some" : @"context",
@"trace" : @ { @"trace_id" : @"1234567890", @"span_id" : @"1234567890" }
@"trace" : @ { @"trace_id" : @"1234567890", @"span_id" : @"1234567890" },
@"app" : @ { @"in_foreground" : @(YES) }
};
[self compareDict:expectedContext withDict:event.context];
XCTAssertNil(event.context[@"traceContext"]);
}

- (void)testAppContextInForegroundTrue_IsTrue
{
[self isValidReport:@"Resources/fatal-error-notable-addresses"];
NSDictionary *rawCrash = [self getCrashReport:@"Resources/fatal-error-notable-addresses"];
SentryCrashReportConverter *reportConverter =
[[SentryCrashReportConverter alloc] initWithReport:rawCrash inAppLogic:self.inAppLogic];

SentryEvent *event = [reportConverter convertReportToEvent];
NSDictionary *expectedContext = @{ @"app" : @ { @"in_foreground" : @(YES) } };
[self compareDict:expectedContext withDict:event.context];
}

- (void)testAppContextInForegroundFalse_IsFalse
{
NSMutableDictionary *rawCrash =
[self getCrashReport:@"Resources/fatal-error-binary-images-simulator"].mutableCopy;

NSMutableDictionary *systemDict =
[[NSMutableDictionary alloc] initWithDictionary:rawCrash[@"system"]];
NSMutableDictionary *applicationStats =
[[NSMutableDictionary alloc] initWithDictionary:systemDict[@"application_stats"]];
applicationStats[@"application_in_foreground"] = @(NO);
systemDict[@"application_stats"] = applicationStats;
rawCrash[@"system"] = systemDict;

SentryCrashReportConverter *reportConverter =
[[SentryCrashReportConverter alloc] initWithReport:rawCrash inAppLogic:self.inAppLogic];

SentryEvent *event = [reportConverter convertReportToEvent];

XCTAssertEqual(event.context[@"app"][@"in_foreground"], @(NO));
}

- (void)testAppContextInForegroundNil_IsNil
{
[self isValidReport:@"Resources/fatal-error-binary-images-simulator"];
NSMutableDictionary *rawCrash =
[self getCrashReport:@"Resources/fatal-error-binary-images-simulator"].mutableCopy;

NSMutableDictionary *systemDict =
[[NSMutableDictionary alloc] initWithDictionary:rawCrash[@"system"]];
NSMutableDictionary *applicationStats =
[[NSMutableDictionary alloc] initWithDictionary:systemDict[@"application_stats"]];
applicationStats[@"application_in_foreground"] = nil;
systemDict[@"application_stats"] = applicationStats;
rawCrash[@"system"] = systemDict;

SentryCrashReportConverter *reportConverter =
[[SentryCrashReportConverter alloc] initWithReport:rawCrash inAppLogic:self.inAppLogic];

SentryEvent *event = [reportConverter convertReportToEvent];

XCTAssertNil(event.context[@"app"][@"in_foreground"]);
}

/**
* Uses two valid crash reports taken from a simulator, with matching scope data.
*/
Expand Down

0 comments on commit 0aa3e78

Please sign in to comment.