Crash & error reporting
Crashes are captured automatically — see Crashes. This page covers what you report from code: errors and exceptions your app catches and recovers from. Such reports are grouped into issues like crashes, so you get statistics and a breakdown by device and iOS version.
Report a handled error
- Objective-C
- Swift
NSError *error = [NSError errorWithDomain:@"com.example.errors.ServerIsDown"
code:10234
userInfo:@{@"key1": @"value1",
@"key2": @"value2"}];
[Bugsee logError:error];
let error = NSError(domain: "com.example.errors.ServerIsDown",
code: 10234,
userInfo: ["key1": "value1", "key2": "value2"])
Bugsee.logError(error: error)
Errors are grouped by code, domain and the location of the call. Keep the domain and code
stable — an arbitrary value in the domain splits one problem into many issues. Put variable data
into userInfo instead.
Report a handled exception
- Objective-C
- Swift
@try {
[self applyCoupon:code];
} @catch (NSException *exception) {
[Bugsee logException:exception completion:nil];
}
// Or describe the exception by name and reason
[Bugsee logException:@"CouponError"
reason:@"Coupon service returned an empty response"
completion:nil];
// From an NSException your code caught, for example in an Objective-C library
Bugsee.logException(exception: exception, completion: nil)
// Or describe the exception by name and reason
Bugsee.logException(name: "CouponError",
reason: "Coupon service returned an empty response",
completion: nil)
Domain and frames to skip
Two more overloads take an exception domain and the number of frames to skip:
- Objective-C
- Swift
[Bugsee logException:exception domain:@"Payments" skipFrames:1 completion:nil];
[Bugsee logException:@"CouponError"
reason:@"Coupon service returned an empty response"
domain:@"Payments"
skipFrames:1
completion:nil];
Bugsee.logException(exception: exception, domain: "Payments", skipFrames: 1, completion: nil)
Bugsee.logException(name: "CouponError",
reason: "Coupon service returned an empty response",
domain: "Payments",
skipFrames: 1,
completion: nil)
domainis recorded with the report. It may benil.skipFramesis how many top frames of the stack recorded for the report are left out of its signature, which groups reports into issues. Use it when every report comes through the same helper of yours, so the helper's frames do not make all of them one issue. A negative value counts as0.
Completion
The completion block runs once the report has been handed over for filing, and also when
nothing is filed (on the simulator, on Mac Catalyst, or while the SDK is stopped), so code that
waits for it is never left hanging. It can be nil.
Labels on these reports
logError: and logException take no labels. Add them to the report in a
report handler, or in bugseeAttachmentsForReport: of your
BugseeDelegate. Both see every report, so check report.type: handled errors and exceptions are
BugseeReportTypeError.
- Objective-C
- Swift
- (NSArray<BugseeAttachment *> *)bugseeAttachmentsForReport:(BugseeReport *)report {
if ([report.type isEqualToString:BugseeReportTypeError] &&
![report.labels containsObject:@"checkout"]) {
report.labels = [report.labels arrayByAddingObject:@"checkout"];
}
return @[];
}
func bugsee(attachmentsFor report: BugseeReport) -> [BugseeAttachment] {
if report.type == BugseeReportTypeError && !report.labels.contains("checkout") {
report.labels = report.labels + ["checkout"]
}
return []
}
type tells an error report from a bug or a crash report, but not a logException report from a
logError report, or from an error report Bugsee files on its own (a hang, an HTTP error), so a
label added this way goes on all of them.
When reports are filed
- A call made while the SDK is
Launchingis filed. If recording has not started yet, the report goes out without video and logs. - A call made while the SDK is stopped files nothing, and Bugsee logs that to the console. That
includes a launch that still waits for the app to become active, as after a launch from
application:didFinishLaunchingWithOptions:in a scene-based app. - On simulators and Mac Catalyst
logError:andlogExceptionfile nothing; Bugsee logs a line that says so, andlogExceptionstill calls its completion. Use a real device. - The severity of these reports is
BugseeOptionReportingDefaultErrorPriority(defaultBugseeSeverityHigh). A report handler can change it per report.
Forward unhandled exceptions
If your app installs its own uncaught-exception handler, forward the exception to Bugsee from it so it is reported as a crash:
- Objective-C
- Swift
[Bugsee logUnhandledException:exception completion:^{
// Continue with your own handling
}];
// Or by name and reason
[Bugsee logUnhandledException:@"FatalStateError"
reason:@"Store is corrupted"
completion:nil];
Bugsee.logUnhandledException(exception: exception) {
// Continue with your own handling
}
// Or by name and reason
Bugsee.logUnhandledException(name: "FatalStateError",
reason: "Store is corrupted",
completion: nil)
On simulators and Mac Catalyst nothing is filed; the completion is still called.
Test crash reporting
testCrash throws an uncaught Objective-C exception, so you can check that crashes reach your
dashboard:
- Objective-C
- Swift
[Bugsee testCrash];
Bugsee.testCrash()
Run it on a device, with the app started from the Home Screen rather than from Xcode: a debugger
catches the crash before Bugsee does. The crash report is sent on the next launch. In 6.x this was
testExceptionCrash / testSignalCrash.