> On Dec 21, 2015, at 9:12 PM, Charles Srstka via swift-evolution 
> <[email protected]> wrote:
> 
> And my two cents is:
> 
> NSError is antiquated, and enums conforming to ErrorType, with associated 
> types on the case values, are much better. They are cleaner, they are easier 
> to use, and they are nicer to look at.

Digressing a bit, I’ve moved away from enums and toward structs for custom 
ErrorTypes, for several reasons:

1. Associated values are tuples. This is a big problem in a public API. Any 
tuple change is a breaking change, and errors thus cannot gain any new 
diagnostic information with breaking the API:

    enum MyError: ErrorType
        {
        case FileNotFound(url: String) // 1.0
        }

    ↓

    enum MyError: ErrorType
        {
        case FileNotFound(url: String, errno: Int?) // Oops! New major release
        }

Structs allow for future expansion:

    struct FileNotFound: ErrorType
        {
        let url: String  // 1.0
        }

    ↓

    struct FileNotFound: ErrorType
        {
        let url: String
        let errno: Int?  // No problem! 1.1
        }

2. Structs allow error-specific helper methods and derived properties, which 
can be useful.

3. Structs can implement protocols, which allow shared handling of error cases 
with shared structure.

> Comparing them is nicer:
> 
> if case let .FileNotFound(url) = error {
>     // handle the error
> }

4. But comparing structs is nicer still, especially when dealing with an 
optional error. With an enum:

    func handleFileNotFound(error: ErrorType?)
        {
        if let error = error
            {
            if case MyError.FileNotFound(let url) = error
                { print(url) }
            }
        }

But if it’s a struct:

    func handleFileNotFound(error: ErrorType?)
        {
        if let error = error as? MyError.FileNotFound
            { print(error.url) }
        }

Or if you don’t need the wrapped value:

    func handleFileNotFound(error: ErrorType?)
        {
        if error is MyError.FileNotFound
            { retry() }
        }

So much more readable than the “if let, if case let” dance!

Hmm, I wonder if #1 or #4 suggest any language changes to propose for this list.

The one big advantage of the error enum is one can use it to enforce handling 
of all error types in a switch — a need which I have yet to encounter in 
practice.

Cheers,

Paul


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to