How to rethrow error from .catch() ?
tkafka opened this issue · 2 comments
I have a function that calls a promise, processes the result (in .then
), logs error (in .catch
), but I would still like to return either fulfilled or rejected promise (so that caller knows if the call succeeded).
However, I can't find how to rethrow the error - I tried this, but Swift tells me that Declared closure result 'Error' is incompatible with contextual type 'Void'
:
.catch(on: .main) { error -> Error in
log(error.localizedDescription)
return error
}
Similarly, when I try to rethrow the error, I get Invalid conversion from throwing function of type '(Error) throws -> Void' to non-throwing function type '(Error) -> Void'
:
.catch(on: .main) { error -> Error in
log(error.localizedDescription)
throw error
}
The whole code:
func doSomething() -> Promise<Bool> {
syncStuff() // returns Promise<Bool>
.then(on: .main) { didSync -> Bool in
log(didSync ? "Synced some items" : "No items needed syncing")
return didSync
}
// this doesn't compile
.catch(on: .main) { error -> Error in
log("Error syncing items: \(error.localizedDescription)")
return error
}
// this doesn't compile either
.catch(on: .main) { error in
log("Error syncing items: \(error.localizedDescription)")
throw error
}
}
Have you looked at recover? You should be able to pass the original error onwards like so:
.recover { error in
// Log error here.
return Promise(error)
}
@jeff-h Aha, thank you! I am reading the spec closely now, and it seems that my expectations were wrong - catch
actually 'rethrows' automatically (so that the .then
after it doesn't run):
catch operator expects one argument - a block, which has the error that the promise was rejected with as an argument. The operator itself implicitly returns another promise, that is rejected with the same error.
I came from javascript world, where Promise's catch
actually behaves like recover
, so I expected this to apply everywhere. Apparently, these semantics varies across languages.