Throwing an error from a Promise.

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Throwing an error from a Promise.

uris77
I want to do something like this:

blocking {
   def errors = validate(parse(Map))
   if(errors) {
      return errors
   }
   doSomethingWithRequest(parse(Map))
} onError { errors ->
    response.status(INVALID_INPUT_CODE)
   render json([errors: errors])
} then { someList - >
   render json(someList)
}



But I'm not sure how to return an error so it gets picked up on the onError block.
Reply | Threaded
Open this post in threaded view
|

Re: Throwing an error from a Promise.

Luke Daley
Administrator
You just need to throw an exception in your blocking() block. 

However, where is the blocking here? Is it validate()? also, what does doSomethingWithRequest()? do?

The reason I ask is that for best performance, you need to do a little work as possible in the blocking {} block. If I understand what you’re trying to do I can give you some more help.

On 2 October 2014 at 5:36:40 am, uris77 [via Ratpack Forum] ([hidden email]) wrote:

I want to do something like this:

blocking {
   def errors = validate(parse(Map))
   if(errors) {
      return errors
   }
   doSomethingWithRequest(parse(Map))
} onError { errors ->
    response.status(INVALID_INPUT_CODE)
   render json([errors: errors])
} then { someList - >
   render json(someList)
}



But I'm not sure how to return an error so it gets picked up on the onError block.


If you reply to this email, your message will be added to the discussion below:
http://forum.ratpack.io/Throwing-an-error-from-a-Promise-tp675.html
To start a new topic under Ratpack Forum, email [hidden email]
To unsubscribe from Ratpack Forum, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Throwing an error from a Promise.

uris77
I'm basically trying to make sure certain fields are present in the body of a "post" before forwarding it to the core logic in another module. I'm basically trying to test out Michael Feather's recommendations in his talk about Error handling (http://vimeo.com/99668845). He postulates that all error handling  be done on the 'borders' and keep the core logic clean without polluting it with null checks etc. Of course, I can also have a thin layer surrounding the guice module that validates input, but then I would still need to throw an error (an exception in this case, I guess).
Reply | Threaded
Open this post in threaded view
|

Re: Throwing an error from a Promise.

Luke Daley
Administrator
Where's the blocking in the validation though?

To be clear Ratpack’s context.parse() isn’t blocking because the data is already in memory.

On 2 October 2014 at 8:39:16 am, uris77 [via Ratpack Forum] ([hidden email]) wrote:

I'm basically trying to make sure certain fields are present in the body of a "post" before forwarding it to the core logic in another module. I'm basically trying to test out Michael Feather's recommendations in his talk about Error handling (http://vimeo.com/99668845). He postulates that all error handling  be done on the 'borders' and keep the core logic clean without polluting it with null checks etc. Of course, I can also have a thin layer surrounding the guice module that validates input, but then I would still need to throw an error (an exception in this case, I guess).


If you reply to this email, your message will be added to the discussion below:
http://forum.ratpack.io/Throwing-an-error-from-a-Promise-tp675p677.html
To start a new topic under Ratpack Forum, email [hidden email]
To unsubscribe from Ratpack Forum, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Throwing an error from a Promise.

uris77
The code I showed is just psuedo code. The blocking code would be doSomethingWithRequest(parse(Map)) . I just simplified it, but in practice it would be something like: someCrudService.create(parse(Map))
Reply | Threaded
Open this post in threaded view
|

Re: Throwing an error from a Promise.

Luke Daley
Administrator
Ok, so in this case it would be better to do:

def map = parse(Map)
// anything else that needs to happen with map

blocking { 
  someCrudService.create(map) 
}  onError {
  render …
}  then {
  render …
}

I can here though that this is kind of inconvenient. It might be better if we supported setting up a pipeline without having to initiate an async op. We could do this by adding the following to ExecControl…

Promise<T> promiseOf(Factory<T> factory)

promiseOf {
  parse(Map)
} map {
  validate(it) // validate returns ‘it’
} blockingMap { v ->
  someCrudService.create(v) // returns v
} onError {
  render “something went wrong: $it"
} then {
  render “saved $it"
}

The only difference would be that you don’t need different error handling strategies (i.e. try/catch and onError).

Maybe syncPromise() is a better name than promiseOf().