Sooner or later, every program crashes or does something weird. Even when the app can recover, it’s best to make the user report problems sooner or later.
Instead of deferring this until later …
do {
try managedObjectContext.save()
} catch let error as NSError {
fatalError("\(error)") // TODO report crash
}
… drop in this micro-framework and have the proper handling in place. You can still worry about the “how” of reporting errors later. But now you will know that errors are handled:
do {
try managedObjectContext.save()
} catch let error as NSError {
applicationError("Saving MOC failed: \(error)")
// Optionally help the user rescue the data:
// saveManagedObjectContextChangesToPlist(managedObjectContext)
return
}
Set-up
Set up the reporter at the beginning of your app. You can do this during bootstrapping or simply call this in AppDelegate:
The default TextEmailer expects your e-mail address in your app’s Info.plist under the key “SupportEmail“. Simply add this key with a string value to make it work.
Usage
The framework includes:
ErrorAlert to display alerts with an error message, informing the user about what happened.
TextEmailer is the default handler of errors. It simply uses the mailto: protocol to send a mail with the system’s default e-mail program. You can drop in anything you’d like as replacement which conforms to the ReportEmailer protocol.
All you have to do is call:
let error: NSError = ...
ErrorAlert(error: error).displayModal()
And you’re set.
Reporting (and e-mailing) additional info
The Report type allows you to wrap any Error with a custom string that should be sent along with the report email.
let error: Error = ...
let logs = previousLogMessages.joined(separator: "\n")
let report = Report(error: error, additionalInfo: logs)
ErrorAlert(report: report).displayModal()
Example: Logging to an array with SwiftyBeaver
If you happen to use SwiftyBeaver for logging, here’s a InMemoryDestination that keeps track of the past log messages so you can send them along in your report:
ErrorHandling
Sooner or later, every program crashes or does something weird. Even when the app can recover, it’s best to make the user report problems sooner or later.
Instead of deferring this until later …
… drop in this micro-framework and have the proper handling in place. You can still worry about the “how” of reporting errors later. But now you will know that errors are handled:
Set-up
Set up the reporter at the beginning of your app. You can do this during bootstrapping or simply call this in AppDelegate:
The default
TextEmailer
expects your e-mail address in your app’sInfo.plist
under the key “SupportEmail“. Simply add this key with a string value to make it work.Usage
The framework includes:
ErrorAlert
to display alerts with an error message, informing the user about what happened.TextEmailer
is the default handler of errors. It simply uses themailto:
protocol to send a mail with the system’s default e-mail program. You can drop in anything you’d like as replacement which conforms to theReportEmailer
protocol.All you have to do is call:
And you’re set.
Reporting (and e-mailing) additional info
The
Report
type allows you to wrap anyError
with a custom string that should be sent along with the report email.Example: Logging to an array with SwiftyBeaver
If you happen to use SwiftyBeaver for logging, here’s a
InMemoryDestination
that keeps track of the past log messages so you can send them along in your report:Convenience methods
Because doing this sucks for unexpected errors, I add something to my projects so I can simply do this:
Or this, to handle cases when I’m stupid:
Or this, when something that may regularly go wrong goes wrong but isn’t handled properly, yet:
Here’s some code to achieve just that, as a bonus:
License
Copyright (c) 2015 Christian Tietze. Distributed under the MIT License.
See LICENSE file for details.