1

I have a chain of throwing calls that I need to catch, and then I need to use their result to - maybe - throw something anyway, despite all of them succeeding:

func a() throws {
    do {
        let b = try b()

        if !b.valid {
            throw SomeError()
        }
    } catch {
        throw SomeError()
    }
}

The problem with this code is:

  • I throw inside a do clause
  • This error will also be caught by catch, which I don't want

Now, one could obviously say that I should just let b outside of do:

func a1() {
    let b: B
    do {
        b = try b()
    } catch {
        throw SomeError()
    }
    
    if !b.valid {
        throw SomeError()
    }
}

But I really don't wanna to that because I have a lot of declarations:

func a2() async throws {
    let b1: B
    let b2: B
    let b3: B
    let b4: B
    let b5: B

    // ...
}

Question: is there any way to throw bypassing the catch? Maybe, I could use Swift labeled statements for this?

Isaaс Weisberg
  • 2,296
  • 2
  • 12
  • 28

1 Answers1

1

Labeled statements are for loops. They are not meant for normal functions. For this you could just go through all the errors you have thrown in do statement in catch block. You just need a switch statement. Like this

enum SomeError: Error {
    case someError
    case anotherError
}

func a() throws {
    do {
        let b = try b()

        if !b.isValid {
            throw SomeError.someError
        }
    } catch {
        switch error {
        case SomeError.someError:
            throw SomeError.someError
        default:
            throw SomeError.anotherError
        }
    }
}
Shreeram Bhat
  • 2,849
  • 2
  • 11
  • 19
  • Well, I will have to unfortunately cast the Error to SomeError, and additionally there needs to be some kind of switch-ability in the SomeError object which we need to introduce and which is not there at the moment. All of this complicates the system, but thank you for the suggestion! – Isaaс Weisberg Aug 08 '22 at 12:59