I've got a bit of a constructed scenario here that's causing a compiler error:
func handle(_ error: Error) {}
func attempt(_ process: @autoclosure () throws -> Void) {
do {
try process()
} catch {
handle(error)
}
}
func receive(completionHandler: @escaping () -> Void) {}
func perform() throws {}
receive {
attempt(try perform())
}
Basically, I have a sort of class-level error handler so I've written a wrapper for throwing calls that catches the error and calls to the error handler. To clean up the call site a little bit, I'm trying to use autoclosure. In the above code, when I call attempt(try perform())
I get a compiler error: Invalid conversion from throwing function of type '() throws -> ()' to non-throwing function type '() -> Void'
. So it's complaining that the callback is being converted to a throwing function, but it shouldn't be since the attempt
function should be swallowing that error.
Additionally, if I wrap that attempt call with a catch like this:
receive {
do {
attempt(try perform())
} catch {}
}
I get a warning: 'catch' block is unreachable because no errors are thrown in 'do' block
. Which is correct, because attempt
is swallowing the error. But without the catch it thinks the function can throw.
Anybody run into this?
EDIT: I wanted to add that calling attempt
from inside the completion handler in receive
is the specific problem. If you call attempt
directly instead of from a callback, the compiler error goes away and things work as expected.