When using Message.Builder.build() an exception is thrown when a required field is not set. Is there way to find out if the exception will be thrown? i.e. something like an iSReadyToBuild? There is a buildPartial method but it does not say whether the build was complete or partial.
The method you are looking for is called "isInitialized()".
Related
I tried to search for this but I could not find a solution anywhere. What I really want to do is that I have a rest service implemented on the cloud (3rd party). From my application I just have a rest client implemented (CXF 2.7.2) which calls this service on the cloud and does some processing before returing the response to the client (primarily native mobile app). So basically it acts as a middleware.
Bascically, I want ot implement a generic exception handling at the middleware (rs-client).
The service implementation (3rd party) is kind of a black box for me and I have no access to their code. When I play with the service using the client, I somtimes get response 400 with a proper message (I finally get a javax.ws.rs.BadRequestException with a message e.g. the input is not valid; and sometimes in certain cases I get a null as a response.
What I want to do is handle all possible (all that I can think of anyway) such cases of responses / codes and convert them to a custom exception. Alongwith this, I also want to handle other cases like timeout etc and convert these also to a custom exception and return it to let the user do what they want to with this exception. Also, log the error along the way.
I saw at various places maybe to handle it using handlemessage but I am not able to arrive at a full implementation.
Your question can have multiple ways for writing right answers. But to help you in first step I provide you a partly answer where we can achieve more to get your problem solved. But please provide more information in your question.
If I understood your question in a right way you can do the following:
For the first part of your question:
What I want to do is handle all possible (all that I can think of anyway) such cases of responses / codes and convert them to a custom exception
If your response code is not a HTTP 200 status code you can catch this and throw a custom exception. After your know its not a HTTP 200 status code its your choice how you want to handle the status code. You can:
just throw a custom exception with a default message or
you can lookup the status code and throw a custom exception with a
specific custom message based on the status code.
Simple code snippet:
if(yourResponse.getStatus() != Response.Status.OK.getStatusCode()){
throw new YourCustomException(yourResponse.getStatus() + " Your message");
}
Your custom Exception Class:
public class YourCustomException extends Exception {
private static final long serialVersionUID = 5724760031556064083L;
public YourCustomException(){
super();
}
public YourCustomException(String message){
super(message);
}
public YourCustomException(String message, Throwable cause){
super(message, cause);
}
public YourCustomException(Throwable cause){
super(cause);
}
}
You should give Retrofit a try, easy to use and light-weight REST client library which has exactly the error handling capabilities you are looking for.
Here is an example for the error handling with the 1.x version https://gist.github.com/benvium/66bf24e0de80d609dac0
If instead you are stuck with JAX-RS/CXF then you need to get a hold of the response object and do your checks there.
http://cxf.apache.org/docs/jax-rs-client-api.html#JAX-RSClientAPI-Handlingexceptions.1
Somewhere in my Spring MVC app I need to add a global error. I no longer have access to any BindingResult, I only have my Request. My error is not the result of any binding issues, it's a global condition. Then I need to attach my new Errors object to the "errors" Req. attribute, so the JSP can display it.
But how to do this? I can't do
Errors errors = new Errors();
errors.reject(....);
request.setAttribute("errors", errors);
because Errors is an interface. The implementations all have to do with 'Binding',like BindException, AbstractBindingResult, MapBindingResult, etc. These all have nothing to do with my case, I don't have a binding field error, it's a general error msg.
Any tips?
Our resolution to this problem: The proper way to handle EXCEPTIONS (rather than VALIDATION errors) is to keep track of our own, custom Request Attribute that we display ourselves in our error area on the JSP.
BindingResult/Errors/etc. are all Binding-related, we can't hack it to handle general exception errors.
We just add a custom Request Attr. called "exceptions" and then our Error section checks for this additonal attribute list to display.
SpringMVC doesn't provide its own 'generic' Error collection.
I'd like my decoration actions to be able to raise ValidationErrors in certain cases. How should I implement that in a simple way, or at least to return a 400 error with error json?
Ok, I figured it out: I should raise an APIException, which encloses the detail message in json.
I'm using Jersey's integrated Jackson processing to transform incoming JSON to a POJO, e.g.:
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response newCustomer( CustomerRepresentation customer)
{
...
}
If a client sends JSON with invalid fields Jersey currently returns a 500 Internal Server Error. Instead, I'd like to return a 400 Bad Request, preferably with some meaningful detail indicating which fields are in error.
Any insight into how this could be accomplished? (At least returning a generic 400 instead of the completely inappropriate 500?)
Update:
Here's the exception being generated server-side, before my handler is invoked:
javax.servlet.ServletException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException:
Unrecognized field "this_isnt_a_known"_field" (Class com.redacted....), not marked as ignorable
I was finally able to work around this problem by implementing an ExceptionMapper to catch the UnrecognizedPropertyException thrown by Jackson and map it to a 400 Bad Request response:
#Provider
public class UnrecognizedPropertyExceptionMapper implements ExceptionMapper<UnrecognizedPropertyException>
{
#Override
public Response toResponse(UnrecognizedPropertyException exception)
{
return Response
.status(Response.Status.BAD_REQUEST)
.entity( "'" + exception.getUnrecognizedPropertyName() + "' is an unrecognized field.")
.type( MediaType.TEXT_PLAIN)
.build();
}
}
I tried mapping status 500 to status 400 with HolySamosa's answer but the exception was not caught by this mapper, and status 500 was still being returned.
After debugging I found that JsonParseException is being thrown and not UnrecognizedPropertyException. This is because I was sending some garbage text (that was not JSON at all).
When I sent a proper JSON from client side, with format that was not appropriate for my DTO on the server side, then I got UnrecognizedPropertyException.
So there are two cases for this:
when you send garbage that is not JSON and
when you send JSON, but it is not a match for your DTO class.
Now I am returning status 400 for both.
In dropwizard land there is an ExceptionMapper called JsonProcessingExceptionMapper that has similar functionality as to what you are looking for. Maybe you can use that for inspiration on how to address your specific issue in a non-dropwizard world.
I've had this same problem... Unfortunately, there's no good way that I know of to intercept the Jackson exception and generate your own error code.
One option you have is to use #JsonIgnoreProperties and then strictly validate the deserialized object. This won't tell you if your sender transmitted junk, but if they missed required fields, you'll catch that.
I cannot find any way to access the actual JSON passed in, other than creating an #Provider class to trap the JSON, validate it, then pass it to Jackson for deserialization.
I am testing how a method handles a 302 HTTPError exception. I tried to stub the one method call to raise one programmatically, however it keep complaining that wrong number of arguments error (0 for 2)
the code tested this particular line:
document = Nokogiri.HTML open(source_url)
and in the spec I stubbed it like this:
subject.stub(:open).and_raise(OpenURI::HTTPError)
subject.should_receive(:ended=).with(true)
subject.update_from_remote
I don't think it is related to Nokogiri.HTML() or Open-uri.open(), so why is this happening?
Also, how would I try to make this HTTPError as a 302 redirect error? Thanks
I found out that OpenURI::HTTPError's constructor requires two parameters. Rspec by default will call the error class's new method with no parameter, which cause this error. So I need to manually create an error object by passing the required parameters.
exception_io = mock('io')
exception_io.stub_chain(:status,:[]).with(0).and_return('302')
subject.stub(:open).with(anything).and_raise(OpenURI::HTTPError.new('',exception_io))
This is a very late reply, but for others who may find this helpful: if you use the FakeWeb gem in conjunction with Nokogiri, you can do this kind of testing without having to get so involved with the internals of the code. You can register a URI with FakeWeb in your test, and tell it what to return. For example:
FakeWeb.register_uri(:get, 'http://www.google.com', :status => ['404', 'Not Found'])
The URI argument you provide needs to match the URI your method is calling. FakeWeb will then intercept the call, and return the status you provide.