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?
source to share
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
}
}
source to share