According to migration guide PromiseKit 6.x changed his policy about catch
blocks. In PMK 4 catch
returned the promise it was attached to. Now catch
is a chain- terminator. I understand why these changes were made but...
In my codebase (connected with PK4) I take some advantages from that catch
returns promise.
func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
synchronizationService.stopAllRunningSingleSynchronizations()
return
authorizationService.save(serverAddress: address, andPort: port)
.then {
self.synchronizationService.startSingleFullSynchronization()
}
.then {
self.authorizationService.markAsServerSynced()
}
.catch { error in
log.error(error)
_ = self.authorizationService.markAsServerUnsynced()
}
}
In this function I make some logic which is in some cases failable. In case of error catch
block should make some logic but I want to also send to loginAndSync
function`s caller a result of this promise (fulfill or reject). Above function can be called for example by ViewController and in ViewController I want to show for example Error or Success Dialog.
This is a reason where I need a two catch
es for one Promise-chain. One for authorizationService
and one for UI
.
Is there any workaround in PromiseKit6 to achieve this?
I found two solutions (workarounds). I have created two answers to separate them. Future readers can decide which one is better or provide new one.
I found (IMO) better workaround. PromiseKit6 introduces very handy method tap
. I have tried use it to resolve my problem.
func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
synchronizationService.stopAllRunningSingleSynchronizations()
return authorizationService.save(serverAddress: address, andPort: port)
.then {
self.synchronizationService.startSingleFullSynchronization()
}
.then {
self.authorizationService.markAsServerSynced()
}
.tap { result in
switch result {
case .rejected(let error):
log.error(error)
_ = self.authorizationService.markAsServerUnsynced()
default: break
}
}
.done {
self.coordinatorDelegate?.handleLoginServerSuccess()
}
}
For doc:
tap
feeds you the current Result for the chain, so is called if the chain is succeeding or if it is failing
So I can provide custom error handling for current state of Promise whit terminating the chain. Promise can be send to sender where I can do another tap
or terminate chain by catch
.