Swift 3 - do-catch and throw

Viewed 4640

When working with a function that throws, we use a do-catch to handle possible errors. Let's say we are writing a function and we want the function to propagate the error:

public func myFunc() throws
{
    do
    {
        let obj = try convert(param: 42)
        // work with obj...
    }
    catch
    {
        print("failed: \(String(describing: error))")
        throw MyError.ConversionFailed
    }
}

That's great. But, let's say now we have custom logic in myFunc that might cause the function to throw a different type of error:

public func myFunc() throws
{
    do
    {
        let obj = try convert(param: 42)
        // work with obj...
        if obj is Array
        {
            // great, continue working with obj...
        }
        else 
        {
            throw MyError.NotAnArray
        }
    }
    catch
    {
        print("failed: \(String(describing: error))")
        throw MyError.ConversionFailed
    }
}

But this wouldn't work: the inner throw will be caught by do-catch and myFunc will just throw the error ConversionFailed, instead of the NotAnArray error.

One way to make this to work is:

public func myFunc() throws
{
    do
    {
        let obj = try convert(param: 42)
        // work with obj...
        if obj is Array
        {
            // great, continue working with obj...
        }
        else 
        {
            throw MyError.NotAnArray(object: obj)
        }
    }
    catch MyError.NotAnArray(let obj)
    {
        throw MyError.NotAnArray(object: obj)
    }
    catch
    {
        print("failed: \(String(describing: error))")
        throw MyError.ConversionFailed
    }
}

That works, but it seems repetitive, especially when there are associated values, and I might need several catches if the custom logic is complex. Is there a better way of doing this?

1 Answers
Related