Swift Error Handling

I often write blog posts for my own sake, but publish them in the event that others may find the information useful.
Today, I wanted to post a quick reference to Error handling in Swift and the syntax for casting and binding an error that is caught in a do-catch statement. I’m finding quite often what you’ll find on the internet is you can catch certain error types, but they don’t assign it to a variable, for example if you want to wrap that error into another Error type that makes your API more contstrained in terms of what kind of errors you should expect to handle in your UI.
For example, it’s not unusual for me to have an error type like this:

public enum SyncError: Error {
    
    /// if for example the pre-conditions for Cloud Sync to work are not met, this could be the result.
    /// actual use cases would be for example if you're not signed into iCloud.
    case initializationFailed(details: String)
    
    /// if you are performing an operation that expects there to be no file at a specific location but there is.
    case fileAlreadyExists(filename: String)
    
    /// if you try to upload a file with no data, or the file doesn't exist in remote
    case noContent(filename: String)
    
    /// wraps an error thrown from FileManager APIs
    case fileManager(error: Error)
    
    /// Just for situations that are unlikely to happen.
    case unexpected(details: String)
}

So there are times where you want to perform a do-catch but then catch certain error types and re-package them before finishing up. In this case below, it’s some body of a method that has to call a completion block on a completion queue with this signature:

(_ success: Bool, _ errors: [SyncError]?) -> Void
do {
      // DO SOME STUFF REQUIRING A try STATEMENT    

} catch let e as SyncError {
    // you see on the line above how you cast and assign the SyncError to a value
    completionQueue.async {
       completion(false, [e])
    }
} catch let e {
    completionQueue.async {
       completion(false, [SyncError.fileManager(error: e)])
    }
}

And that’s it! I only wrote this here because I didn’t want to google around again should I forget that syntax.

Leave a comment