Search code examples
iosswiftcombine

Handle error in flatmap when using chaining of publishers


I am trying use Combine in my Swift application and have problem in my following code:

//Get it from local storage(realm)
    voucherCodeStorageProvider.fetchVoucherCode(voucherId).flatMap { (code) -> AnyPublisher<String?, Error> in
            if let code = code {
                return Just(code).setFailureType(to: Error.self).eraseToAnyPublisher()
            }
            //If not found in storage, Get it from api
            return self.voucherCodeProvider.fetchVoucherCode(voucherId: voucherId).handleEvents( receiveOutput: { code in
                guard let code = code else { return }
                _ = self.voucherCodeStorageProvider.saveVoucherCode(code, voucherId)
            }).mapError{ $0 as Error }.eraseToAnyPublisher()
        }.eraseToAnyPublisher()

Above fetchVoucherCode is currently publishing an error, now I want to catch that error and do task that I perform after nil check in my code. But I am not able to catch error here. How can I catch an error in flatmap and can perform some operation like I have above?


Solution

  • I did it using catch before flatmap. Below is my working code:

    voucherCodeStorageProvider.fetchVoucherCode(voucherId).catch { _ in
            return self.voucherCodeProvider.fetchVoucherCode(voucherId: voucherId).handleEvents( receiveOutput: { code in
                guard let code = code else { return }
                _ = self.voucherCodeStorageProvider.saveVoucherCode(code, voucherId)
            }).mapError{ $0 as Error }.eraseToAnyPublisher()
            
        }.flatMap { (code) -> AnyPublisher<String?, Error> in
            return Just(code).setFailureType(to: Error.self).eraseToAnyPublisher()
        }.eraseToAnyPublisher()