Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add onCrashedLastRun #808

Merged
merged 21 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0961c89
feat: Add onCrashedLastRun
philipphofmann Oct 21, 2020
416321d
Committing formatted code
Oct 21, 2020
bd556f4
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 12, 2020
fd0d836
Call callback only for first crash event
philipphofmann Nov 12, 2020
eb52611
Add comment about downside of callback
philipphofmann Nov 12, 2020
29ce980
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 12, 2020
cebee03
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 16, 2020
16ff083
Check if event contains unhandled exception
philipphofmann Nov 16, 2020
c99eeab
Committing formatted code
Nov 16, 2020
cc4c291
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 16, 2020
1633157
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 18, 2020
dacc561
Add tests
philipphofmann Nov 19, 2020
b3e49d8
Undo changes in iOS-Swift AppDelegate
philipphofmann Nov 19, 2020
80439ea
Remove SentryId from SentryDefines
philipphofmann Nov 19, 2020
fa66553
Update changelog
philipphofmann Nov 19, 2020
44b4f5e
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 20, 2020
01ee8fc
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 23, 2020
8a9faea
Toggle BOOL after action for callOnCrashedLastRun
philipphofmann Nov 24, 2020
b04e388
Fix typos
philipphofmann Nov 24, 2020
4950e6b
Add captureCrash to SentryClient
philipphofmann Nov 24, 2020
008008d
Merge branch 'master' into feat/on-crashed-last-run
philipphofmann Nov 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## unreleased

- feat: Add onCrashedLastRun #808
- feat: Add SentrySdkInfo to SentryOptions #859

## 6.0.9
Expand Down
5 changes: 5 additions & 0 deletions Sources/Sentry/Public/SentryDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ typedef SentryBreadcrumb *_Nullable (^SentryBeforeBreadcrumbCallback)(
*/
typedef SentryEvent *_Nullable (^SentryBeforeSendEventCallback)(SentryEvent *_Nonnull event);

/**
* A callback to be notified when the last program execution terminated with a crash.
*/
typedef void (^SentryOnCrashedLastRunCallback)(SentryEvent *_Nonnull event);

/**
* Block can be used to determine if an event should be queued and stored
* locally. It will be tried to send again after next successful send. Note that
Expand Down
11 changes: 11 additions & 0 deletions Sources/Sentry/Public/SentryOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ NS_SWIFT_NAME(Options)
*/
@property (nonatomic, copy) SentryBeforeBreadcrumbCallback _Nullable beforeBreadcrumb;

/**
* This gets called shortly after the initialization of the SDK when the last program execution
* terminated with a crash. It is not guaranteed that this is called on the main thread.
*
* @discussion This callback is only executed once during the entire run of the program to avoid
* multiple callbacks if there are multiple crash events to send. This can happen when the program
* terminates with a crash before the SDK can send the crash event. You can look into beforeSend if
* you prefer a callback for every event.
*/
@property (nonatomic, copy) SentryOnCrashedLastRunCallback _Nullable onCrashedLastRun;

/**
* Array of integrations to install.
*/
Expand Down
51 changes: 44 additions & 7 deletions Sources/Sentry/SentryClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import "SentryMessage.h"
#import "SentryMeta.h"
#import "SentryOptions.h"
#import "SentrySDK+Private.h"
#import "SentryScope.h"
#import "SentryStacktraceBuilder.h"
#import "SentryThreadInspector.h"
Expand Down Expand Up @@ -175,13 +176,19 @@ - (SentryEvent *)buildErrorEvent:(NSError *)error
return event;
}

- (SentryId *)captureEvent:(SentryEvent *)event
withSession:(SentrySession *)session
withScope:(SentryScope *)scope
- (SentryId *)captureCrashEvent:(SentryEvent *)event withScope:(SentryScope *)scope
{
return [self sendEvent:event withScope:scope alwaysAttachStacktrace:NO isCrashEvent:YES];
}

- (SentryId *)captureCrashEvent:(SentryEvent *)event
withSession:(SentrySession *)session
withScope:(SentryScope *)scope
{
SentryEvent *preparedEvent = [self prepareEvent:event
withScope:scope
alwaysAttachStacktrace:NO];
alwaysAttachStacktrace:NO
isCrashEvent:YES];
return [self sendEvent:preparedEvent withSession:session];
}

Expand All @@ -198,10 +205,22 @@ - (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope
- (SentryId *)sendEvent:(SentryEvent *)event
withScope:(SentryScope *)scope
alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace
{
return [self sendEvent:event
withScope:scope
alwaysAttachStacktrace:alwaysAttachStacktrace
isCrashEvent:NO];
}

- (SentryId *)sendEvent:(SentryEvent *)event
withScope:(SentryScope *)scope
alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace
isCrashEvent:(BOOL)isCrashEvent
{
SentryEvent *preparedEvent = [self prepareEvent:event
withScope:scope
alwaysAttachStacktrace:alwaysAttachStacktrace];
alwaysAttachStacktrace:alwaysAttachStacktrace
isCrashEvent:isCrashEvent];

if (nil != preparedEvent) {
[self.transport sendEvent:preparedEvent];
Expand Down Expand Up @@ -289,6 +308,17 @@ - (BOOL)checkSampleRate:(NSNumber *)sampleRate
- (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
withScope:(SentryScope *)scope
alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace
{
return [self prepareEvent:event
withScope:scope
alwaysAttachStacktrace:alwaysAttachStacktrace
isCrashEvent:NO];
}

- (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
withScope:(SentryScope *)scope
alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace
isCrashEvent:(BOOL)isCrashEvent
{
NSParameterAssert(event);
if ([self isDisabled]) {
Expand Down Expand Up @@ -340,12 +370,12 @@ - (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
|| (nil != event.exceptions && [event.exceptions count] > 0);

BOOL debugMetaNotAttached = !(nil != event.debugMeta && event.debugMeta.count > 0);
if (shouldAttachStacktrace && debugMetaNotAttached) {
if (!isCrashEvent && shouldAttachStacktrace && debugMetaNotAttached) {
event.debugMeta = [self.debugMetaBuilder buildDebugMeta];
}

BOOL threadsNotAttached = !(nil != event.threads && event.threads.count > 0);
if (shouldAttachStacktrace && threadsNotAttached) {
if (!isCrashEvent && shouldAttachStacktrace && threadsNotAttached) {
event.threads = [self.threadInspector getCurrentThreads];
}

Expand All @@ -366,6 +396,13 @@ - (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
event = self.options.beforeSend(event);
}

if (isCrashEvent && nil != self.options.onCrashedLastRun && !SentrySDK.crashedLastRunCalled) {
// We only want to call the callback once. It can occur that multiple crash events are
// about to be sent.
self.options.onCrashedLastRun(event);
SentrySDK.crashedLastRunCalled = YES;
}

return event;
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/Sentry/SentryHub.m
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,13 @@ - (void)captureCrashEvent:(SentryEvent *)event
// It can be that there is no session yet, because autoSessionTracking was just enabled and
// there is a previous crash on disk. In this case we just send the crash event.
if (nil != crashedSession) {
[client captureEvent:event withSession:crashedSession withScope:self.scope];
[client captureCrashEvent:event withSession:crashedSession withScope:self.scope];
[fileManager deleteCrashedSession];
return;
}
}

[self captureEvent:event withScope:self.scope];
[client captureCrashEvent:event withScope:self.scope];
}

- (SentryId *)captureEvent:(SentryEvent *)event
Expand Down
4 changes: 4 additions & 0 deletions Sources/Sentry/SentryOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ - (void)validateOptions:(NSDictionary<NSString *, id> *)options
self.beforeBreadcrumb = options[@"beforeBreadcrumb"];
}

if (nil != options[@"onCrashedLastRun"]) {
self.onCrashedLastRun = options[@"onCrashedLastRun"];
}

if (nil != options[@"integrations"]) {
self.integrations = options[@"integrations"];
}
Expand Down
11 changes: 11 additions & 0 deletions Sources/Sentry/SentrySDK.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
@implementation SentrySDK

static SentryHub *currentHub;
static BOOL crashedLastRunCalled;

@dynamic logLevel;

Expand All @@ -43,6 +44,16 @@ + (void)setCurrentHub:(SentryHub *)hub
}
}

+ (BOOL)crashedLastRunCalled
{
return crashedLastRunCalled;
}

+ (void)setCrashedLastRunCalled:(BOOL)value
{
crashedLastRunCalled = value;
}

+ (void)startWithOptions:(NSDictionary<NSString *, id> *)optionsDict
{
NSError *error = nil;
Expand Down
8 changes: 5 additions & 3 deletions Sources/Sentry/include/SentryClient+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ NS_ASSUME_NONNULL_BEGIN
withSession:(SentrySession *)session
withScope:(SentryScope *)scope;

- (SentryId *)captureEvent:(SentryEvent *)event
withSession:(SentrySession *)session
withScope:(SentryScope *)scope;
- (SentryId *)captureCrashEvent:(SentryEvent *)event withScope:(SentryScope *)scope;

- (SentryId *)captureCrashEvent:(SentryEvent *)event
withSession:(SentrySession *)session
withScope:(SentryScope *)scope;

@end

Expand Down
5 changes: 5 additions & 0 deletions Sources/Sentry/include/SentrySDK+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ NS_ASSUME_NONNULL_BEGIN

+ (void)captureCrashEvent:(SentryEvent *)event;

/**
* SDK private field to store the state if onCrashedLastRun was called.
*/
@property (nonatomic, class) BOOL crashedLastRunCalled;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ class SentrySessionTrackerTests: XCTestCase {
}

private func assertNoInitSessionSent() {
let eventWithSessions = fixture.client.captureEventWithSessionArguments.map({ triple in triple.second })
let eventWithSessions = fixture.client.captureCrashEventWithSessionArguments.map({ triple in triple.second })
let errorWithSessions = fixture.client.captureErrorWithSessionArguments.map({ triple in triple.second })
let exceptionWithSessions = fixture.client.captureExceptionWithSessionArguments.map({ triple in triple.second })

Expand All @@ -462,7 +462,7 @@ class SentrySessionTrackerTests: XCTestCase {
}

private func assertSessionsSent(count: Int) {
let eventWithSessions = fixture.client.captureEventWithSessionArguments.count
let eventWithSessions = fixture.client.captureCrashEventWithSessionArguments.count
let errorWithSessions = fixture.client.captureErrorWithSessionArguments.count
let exceptionWithSessions = fixture.client.captureExceptionWithSessionArguments.count
let sessions = fixture.client.sessions.count
Expand Down Expand Up @@ -496,7 +496,7 @@ class SentrySessionTrackerTests: XCTestCase {
sut.start()
SentrySDK.captureCrash(Event())

if let session = fixture.client.captureEventWithSessionArguments.last?.second {
if let session = fixture.client.captureCrashEventWithSessionArguments.last?.second {
assertSession(session: session, started: sessionStartTime, status: SentrySessionStatus.crashed, duration: 5)
} else {
XCTFail("No session sent with event.")
Expand Down
2 changes: 2 additions & 0 deletions Tests/SentryTests/SentryClient+TestInit.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#import "SentryTransport.h"
#import <Sentry/Sentry.h>

@class SentryCrashAdapter;

NS_ASSUME_NONNULL_BEGIN

/** Expose the internal test init for testing. */
Expand Down
Loading