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?