users@jersey.java.net

Re: [Jersey] Idea for new contribution -- a pattern for handling HTTP errors as Java exceptions?

From: Julio Faerman <jfaerman_at_gmail.com>
Date: Fri, 24 Oct 2008 09:30:35 -0200

Very intersting, something like that would be really helpful.
I just question the use of exception when there are multiple errors. For
example if i have 5 unparseable fields or 10 invalid records in a batch. To
handle this properly with exceptions, i think it would require a weird
"CompositeException".


On Thu, Oct 23, 2008 at 10:22 PM, Craig McClanahan <Craig.McClanahan_at_sun.com
> wrote:

> In addition to the jersey-multipart stuff I contributed for creating and
> consuming MIME multipart messages (see the "jersey-multipart" module in the
> "contribs" directory), one of the other things I've been doing in my "day
> job" work is defining a common "best practices" approach to use for error
> handling in RESTful web services. We all know that JAX-RS (and therefore
> Jersey) lets us create and consume HTTP messages with any needed status
> code, but that still doesn't address two concerns:
>
> * Ensuring that every developer on the team uses the same HTTP status code
> for the same "error" scenario, across multiple services (so that the
> service APIs
> all look like they actually came from the same company :-).
>
> * Passing error messages in a consistent format that the client can rely
> on, and
> parse to good effect. For example, if your API offers a POST URI to
> create a new
> resource, but several of the input fields in the entity have incorrect or
> missing values,
> it would be nice to have a data structure that lets me include zero or
> more error
> messages, optionally tagged to the corresponding field names (so that a
> client side
> UI can present them nicely).
>
> Does this sound like an interesting problem to anyone else?
>
> The solution being developed by our team started from the notion that Java
> developers are used to handling "exceptional" situations with ...
> "exceptions" :-). Back in the Jersey 0.8 or so time frame, JAX-RS added the
> concept of an ExceptionMapper, which basically acts like a MessageBodyWriter
> when the resource method itself throws an exception. So, maybe we can give
> the server side developer a set of well defined exception classes (and
> corresponding exception mappers) that the resource method can just throw,
> and let the library deal with setting the correct status code and an entity
> containing the right message infomation.
>
> On the server side, your resource method code might look something like
> this:
>
> @GET
> @Path("/customers/{id}")
> @Produces({"application/json","application/xml","text/xml"})
> public Customer find(@PathParam("id") String id) {
> // Finder method returns null if no such customer exists
> Customer cust = MyBusinessLogic.findCustomerById(id);
> if (cust != null) {
> return cust; // Use the provider for formatting this response
> } else {
> // NotFoundException is a RuntimeException so you do not need to
> // declare it in a throws clause, but you SHOULD javadoc it
> throw new NotFoundException("Customer '" + id + "' does not
> exist");
> }
> }
>
> The library would provide an exception mapper that enforces our "best
> practice" policy to use an HTTP 404 "Not Found" status for this condition,
> and package an appropriate message body containing the message text, in a
> standard XML or JSON format.
>
> For extra credit, I write client SDKs for our APIs as well. Why can't we
> make it possible for the client developer to reason in exceptions just like
> the server side developer can? That's actually pretty straightforward, if
> you have a client side library that knows how to map HTTP error responses
> back into an exception again.
>
> Let's imagine a client side business logic class (based on jersey-client)
> that abstracts calls to the above service with a nice Java API. The code to
> call the server method described above might look like:
>
> public class CustomerService {
>
> WebResource service = ...; // See jersey-client examples for setting
> this up
>
> public Customer findCustomerById(String id) {
> try {
> return service.
> path("customers/" + id).
> accept("text/xml").
> get(Customer.class);
> } catch (UniformInterfaceException e) {
> throw ErrorsHelper.asException(e.getResponse());
> }
> }
>
> }
>
> where ErrorsHelper.asException analyzes the HTTP status of the response and
> synthesizes an appropriate exception (in our case, turning a 404 into a
> NotFoundException) and grabs the relevant information out of the response
> body (including the error message text).
>
> So, does this sort of thing sound like something you might use? It would
> be pretty straightforward to generalize what I've already got working to
> make it fit in with Jersey (that's mostly a matter of a Maven based build
> environment plus package name changes), if it sounds like this would be
> generally useful.
>
> Craig
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>