Reputation: 1469
I'm doing some networking and want to throw from the trailing closure according to the response.
As a result, I've found that I'm unable to do so with an "invalid conversion" error.
I've reduced the problem to a minimal example - no cliches allowed:
func innerClosure(a: String, completion: (String)->Void) {
completion(a + ", World")
}
func iCanThrow(name: String, closure: (String,(String)->Void)->(Void) ) throws {
closure(name, {response in
print (response)
if response == "Hello, World" {
throw ClicheError.cliche
}
})
}
try iCanThrow(name: "Hello", closure: innerClosure)
Ad you can see I want to throw a ClicheError
from within the trailing closure - but the specific error is Invalid conversion from throwing function of type '(String) throws -> Void' to non-throwing function type '(String) -> Void'
I've tried using various combinations of throws
and rethrows
but I simply can't get this to work - even if I get the inner closure to throw
I get the following:
enum ClicheError: Error {
case cliche
case latecliche
}
func innerClosure(a: String, completion: (String) throws ->Void) {
try? completion(a + ", World")
}
func iCanThrow(name: String, closure: (String,(String) throws ->Void) throws ->(Void) ) throws {
try closure(name, {response in
print (response)
if response == "Hello, World" {
throw ClicheError.cliche
}
})
}
try iCanThrow(name: "Hello", closure: innerClosure)
Which compiles, throws but doesn't actually throw from iCanThrow
- meaning I can't throw!
Upvotes: 0
Views: 272
Reputation: 539765
func innerClosure(a: String, completion: (String) throws ->Void) {
try? completion(a + ", World")
}
does not throw an error because try?
is an “optional try”: It returns an Optional
which is nil
in the case of an error. Here the return value is ignored, so that errors are ignored silently.
What you want is
func innerClosure(a: String, completion: (String) throws ->Void) rethrows {
try completion(a + ", World")
}
which makes innerClosure()
a throwing function only if called with a throwing parameter.
func iCanThrow()
can also be marked as rethrows
instead of throws
because it does not throw an error “on its own.”
See also What are the differences between throws and rethrows in Swift?.
Upvotes: 4