1

So I'm using PromiseKit in my latest swift app to do most of the networking code, along with Alamofire. I'm trying to setup my promises to throw when my returns aren't what I desire - here's what the code looks like:

`

    do{
        firstly({
            try DoStuff.doStuff()
        }).then({ response in
            self.array = response
        }).error { error in
            throw Error.GeneralError
            print(error)
        }

        firstly({
            try DoOtherThing.otherThing()
        }).then({ response in
            self.stuff = response
        }).error{ error in
            throw TransactionError.GeneralError
            print(error)
        }
    } catch {
        let alertController = UIAlertController(title: "Network Error", message: "Network error, please try again", preferredStyle: .Alert)
        let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
            //
        }
        alertController.addAction(OKAction)
        self.presentViewController(alertController, animated: true) {
            //
        }
    }

`

This code works just hunky dory if I don't have the 'throw' statements in there - if I just print the error, or put my alert controller code in there, works as expected. But when I add the throw, I get an compiler red flag on the 'error' line that says Cannot call value of non function type 'ErrorType' Any thoughts? Thanks

2 Answers2

2

The way you would do this with PromiseKit would be something like:

let stuff = firstly {
    try DoStuff.doStuff()
}.then { response in
    self.array = response
}

let otherStuff = firstly {
    try DoOtherThing.otherThing()
}.then { response in
    self.stuff = response
}

when(fulfilled: stuff, otherStuff).catch { _ in
    let alertController = UIAlertController(title: "Network Error", message: "Network error, please try again", preferredStyle: .alert)
    let OKAction = UIAlertAction(title: "OK", style: .default) { (action) in
        //
    }
    alertController.addAction(OKAction)
    self.present(alertController, animated: true) {
        //
    }
}

In the above, I'm assuming that doStuff() and doOtherThing() are both synchronous functions that throw on error. As such, it doesn't make a lot of sense to wrap them in promises unless you are using the results to feed an asynchronous task and then using the result from that.

Daniel T.
  • 32,821
  • 6
  • 50
  • 72
1

I think your understanding of do/catch isn't quite right.

Do/Catch is a synchronous operation only, so to catch the throw, the error must be thrown whilst in the do block. In this case, all you're doing inside the do block is setting up the promise. Should the error condition ever be reached, it will be executed asynchronously in a different context - outside of your do catch block and so cannot be caught.

EDIT: To make it clearer why you are getting the error, here is the method signature for error in PromiseKit:

func error(policy policy: ErrorPolicy = .AllErrorsExceptCancellation, _ body: (ErrorType) -> Void)

The 'body' closure is not declared as throwing so therefore you cannot throw to exit that context. To throw, it would need to be declared like this:

func error(policy policy: ErrorPolicy = .AllErrorsExceptCancellation, _ body: (ErrorType) throws -> Void)

But it can't because it executes it asynchronously.

SeanCAtkinson
  • 753
  • 1
  • 4
  • 15