Unwrap or Throw - Make the Safe Choice Easier

This is not exactly the case:

enum CatError: Error { case hairball }
enum DogError: Error { case chasedSkunk }

func foo(_ f: () throws -> Void) rethrows {
    do { try f() }
    catch { throw CatError.hairball }
}

do {
    try foo{ throw DogError.chasedSkunk }
} catch {
    print(error) // hairball
}

The above rethrows function does not propagate the thrown error, instead creating a new error.

Moreover, a rethrows function is also currently allowed to throw if a local function inside it throws—although this will crash the app if a non-throwing closure was passed to the outer function and the local function does throw.

And also, DispatchQueue.sync (which rethrows) is implemented as simply calling through to a private helper method _syncHelper which is also rethrows, by passing in an unconditionally-throwing closure. The way _syncHelper is written it does in fact only throw errors that originated from the closure passed to sync but that does not have to be the case.

3 Likes