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

How to get event_id from crash report #699

Closed
6 tasks
georges opened this issue Sep 2, 2020 · 13 comments · Fixed by #808
Closed
6 tasks

How to get event_id from crash report #699

georges opened this issue Sep 2, 2020 · 13 comments · Fixed by #808

Comments

@georges
Copy link

georges commented Sep 2, 2020

Platform:

  • iOS
  • tvOS
  • [x ] MacOS
  • watchOS

Swift:

  • Yes -> If yes, which version?
  • [x ] No

sentry-cocoa installed with:

  • [x ] CocoaPods
  • Carthage
  • Manually

Version of sentry-cocoa:
5.2.2


I have following issue:

I'm trying to send a user feedback via API after a crash (https://docs.sentry.io/api/projects/post-project-user-reports/).

On next launch I can detect that the application has crashed by looking at crashLastLaunch property on SentryCrash and retrieve the reportIDs. But the user report API needs an event_id to tie the feedback to the crash. How do I retrieve the event_id from the reports?

@philipphofmann
Copy link
Member

Hi, @georges. We recently added crashedLastRun to SentrySDK. So you don't have to call SentryCrash anymore.

Unfortunately, we don't have a straightforward way to do this right now. The reports are from our internal crash reporting framework, which originates from https://github.com/kstenerud/KSCrash. We convert the reports to SentryEvents with SentryCrashReportConverter and SentryCrashReportSink passes the event to SentrySDK. You could hook into beforeSend and check if the level of the event was fatal and if crashedLastRun is true. In theory, there could be other events with fatal, so you should make sure you only execute this code once. Our SDK only creates fatal events, if your application crashed.

@bruno-garcia
Copy link
Member

@philipphofmann can we add a field called lastEventId (for example, in C#) to SentrySDK and set this value when running the report conversion in SentryCrashReportConverter? That'd mean once Sentry inits, the user would be able to:

if Sentry.crashedLastRun then openUserFeedback(Sentry.LastEventId)

@bruno-garcia
Copy link
Member

Also please note that we plan to implement user-feedback in the SDK in Q4.
We're still considering which API to add.

@georges what kind of API would you expect?

Would a callback to be registered during Sentry SDK init suffice? The callback would be triggered passing the event id as suggested above.

@georges
Copy link
Author

georges commented Sep 16, 2020

A callback would be great but the method you described in first post works too. Basically all that is needed is to know if a crash occurred and retrieve the event_id that can be used to post to the user feedback endpoint.

@philipphofmann
Copy link
Member

@philipphofmann can we add a field called lastEventId (for example, in C#) to SentrySDK and set this value when running the report conversion in SentryCrashReportConverter? That'd mean once Sentry inits, the user would be able to:

if Sentry.crashedLastRun then openUserFeedback(Sentry.LastEventId)

Yep we can do that. I add it to our Backlog.

@philipphofmann philipphofmann linked a pull request Oct 21, 2020 that will close this issue
5 tasks
@philipphofmann
Copy link
Member

philipphofmann commented Oct 21, 2020

Hey @georges, we merged yesterday an API to manually send user feedback to Sentry #805. Now we are working on adding a callback to retrieve the eventId from a crash event in #808. The API would look like this

SentrySDK.start { options in
    // ...
    
    options.onCrashedLastRun = { eventId in
        self.displayUserFeedback(eventId: eventId)
    }
}

// Not a sentry function. Only wraps call to user feedback
func displayUserFeedback(eventId: SentryId) {
		
    // Display UI and get feedback from the user. 

    // Then send feedback to Sentry
    let feedback = SentryUserFeedback(eventId: eventId)
    feedback.comments = "It broke"
    feedback.name = "John Smith"
    feedback.email = "[email protected]"
    SentrySDK.capture(feedback: feedback)
}

Would you be so kind to give us feedback on this one?

@georges
Copy link
Author

georges commented Oct 22, 2020

That design works well. One consideration (I don't know if that's even possible to happen) is wether there can be more than one crash event pending? From what I understand Sentry waits to send crash report on next launch. What if there are two crashes that happened before the app is in a state where Sentry sdk can run again? Would there ever be more than one event? In which case there would be more than one dialog prompting the user which would be odd.

@philipphofmann
Copy link
Member

That's a very good point @georges, there could be more than one crash report. What would you expect in such a case?

@georges
Copy link
Author

georges commented Oct 22, 2020

Ok. In case of multiple consecutive crashes, it's very unlikely that the user would know to provide distinct feedback for each situation that caused a crash. So perhaps have the callback fire once but allow for multiple enventId to be passed as an array?

This way the app could decide to display a dialog only once but send multiple capture with same comments for each eventId or only capture and send feedback for the last eventId in the array or prompt the user for every single one if desired.

philipphofmann added a commit that referenced this issue Nov 25, 2020
Add a callback onCrashedLastRun to SentryOptions that is called by the SDK passing the eventId
when Sentry is initialized and the last program execution terminated with a crash.

Fixes GH-699
@georges
Copy link
Author

georges commented Nov 27, 2020

Pulled tag 6.0.10 and tried the feature in my macOS app. Works great. Thank you @philipphofmann 🙏

One small observation is that i was having problems initializing the onCrashedLastRun when I used the dictionary initializer with startWithOptions (well it initialize fine but it crashed when it tried to invoke the callback). I switched to startWithOptionsObject and it worked fine. Note that I'm using RubyMotion, so it's entirely possible that there is some funkiness going when setting the callback in the value/pair dictionary vs. assigning directly to a property. Nevertheless, thought you should know in case you want to try to replicate using startWithOptions in Objective-C with a dictionary.

@philipphofmann
Copy link
Member

Thanks for the update @georges. The following code works for me:

SentryOnCrashedLastRunCallback callback = ^void(SentryEvent * _Nonnull event) {
    // ...
};

[SentrySDK startWithOptions:@{
    @"dsn": @"__DSN__",
    @"onCrashedLastRun": callback
}];

Which error do you get?

@georges
Copy link
Author

georges commented Nov 30, 2020

What I got looked like an invalid pointer was being called and crashed the calling thread at execution, which lead me to suspect that the callback assignment was not done properly in my setup. Once I switched to using properties it worked fine. Probably something to do with how RubyMotion translates lambda block to be used as callback and maybe that pointer math is not working well on a dictionary or perhaps not retained in memory or something like that. Probably can just ignore this then. Just wanted to mention it in case there was something affecting Objective C for some odd reason.

@philipphofmann
Copy link
Member

Thanks for the detailed update @georges. It's better that to raise a flag when things are uncertain than never raising it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants