google/promises

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.

Screen Shot 2021-04-29 at 14 18 14