Runtime Errors
Despite your best efforts, things will sometimes go wrong while your app is running. In Cocoa, these errors fall into two categories.
Programmer errors are situations that should never happen, which means that they are the result of, well, a mistake you made. (We say they should never happen… but we have made plenty of these.) Examples include not meeting the precondition of a method (the index was not within the array’s bounds), performing an illegal operation (such as force-casting incorrectly or force-unwrapping a nil), or sending a message to an Objective-C object that does not understand it.
Swift alerts you to programmer errors by trapping, which results in stopping the program. Cocoa APIs use Objective-C exceptions. A trap is typically accompanied by a fatal error line in the console, while exceptions have much longer output showing the full stack. Note that Swift does not presently support exceptions.
Recoverable errors, on the other hand, are errors that your application can check for, deal with, and move on from. Examples include being unable to contact a remote server, errors parsing data, or lacking hardware capabilities.
Recoverable errors will be communicated to your code through the return values of methods (such as a nil return). For more sophisticated APIs, especially those involving I/O, an NSError object will be used. You will learn about NSErrorin Chapter 12.
You can code defensively and check preconditions in your own code using assert() and fatalError(). For example:
let condition: Bool = ... assert(condition, "Condition was not met")
fatalError() is useful in methods that are declared to return a value. The Swift compiler requires that all code paths return a value – unless you call a noreturn function like fatalError():
func openFortuneCookie() -> String { if let cookie = cookie { return cookie.fortune } else { fatalError("Must have cookie!") // No return statement } }