Swift 3 - Trick and Throw

When working with a function, throws

we use do-catch

to handle possible errors. Let's say we are writing a function and want the function to propagate an error:

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

      

It's great. But let's say we now have custom logic in myFunc

that can cause the function to generate 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 that won't work: the inner one throw

will be caught do-catch

and it will myFunc

just throw an error ConversionFailed

instead of an error NotAnArray

.

One way to get this to work:

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
    }
}

      

This works, but seems repetitive, especially when there are associated values, and I might need multiple catch

es if the custom logic is tricky. Is there a better way to do this?

+3


source to share


1 answer


If you want to replace the error thrown with convert()

another error, then call convert()

do / catch in the local context. The outer do / catch is unnecessary because the function "automatically" throws errors to the caller (compare How to Pass an Error on the Stack in Swift ).



public func myFunc() throws
{
    let obj: Any // or whatever type convert() returns
    do {
        obj = try convert(param: 42)
    } catch {
        throw MyError.ConversionFailed
    }
    // work with obj...
    if obj is Array {
        // great, continue working with obj...
    } else {
        throw MyError.NotAnArray
    }
}

      

+1


source







All Articles