Reda Lemeden

Reda Lemeden

Indie Developer & Designer

On flatMapThrowing in SwiftNIO


Johannes Weiss answering the question why flatMapThrowing (docs) is not a throwing flatMap:

Functions that have this prototype: f() throws -> EventLoopFuture<Void> are in my view a bit user hostile. They can fail in two different ways: by throwing [and] by returning a failed future. That means a user needs to look for errors in two different places. […] On top of that: If an asynchronous function throws synchronously, is it really asynchronous?

This one caught me off-guard more than once. Considering the signatures of map and flatmap (abridged for brevity):

func map<NewValue>(callback: @escaping (Value) -> NewValue) -> EventLoopFuture<NewValue>
func flatMap<NewValue>(callback: @escaping (Value) -> EventLoopFuture<NewValue>) -> EventLoopFuture<NewValue>

It’s easy to assume that flatMapThrowing is a version of flatMap that takes a throwing closure of type (Value) throws -> EventLoopFuture<NewValue>. But that’s not the case.

func flatMapThrowing<NewValue>(callback: @escaping (Value) throws -> NewValue) -> EventLoopFuture<NewValue>

As for the name of the method, Johannes explains:

Lots of people get confused by this, if I could choose again, I’d probably go for something like combineThrowing or so?