I'm sending a request with form data to ProcessorActionBean for processing. An error occurs, but the ProcessorActionBean does not have a JSP view - it is just for processing form data - so I catch the errors by implementing a ValidationErrorHandler on the ProcessorActionBean, and from within handleValidationErrors(), I redirect it to DisplayerActionBean.
The problem is that the error that caused the method to be run disappears after the redirect. I can put non-error messages in the context, and they'll be shown in the DisplayerActionBean's page, but error messages appear to go to /dev/null.
How do I get the errors to display, too?
The solution turned out to be to:
a) in the handleValidationErrors() method, use a FlashScope to put the validation errors somewhere they'll survive until the next request:
FlashScope scope = FlashScope.getCurrent(getRequest(), true);
scope.put("your_key",listOfValidationErrors);
b) in an Interceptor (I've used a modified ErrorMessageInterceptor), where if you find some errors under your_key, you put them in context's validation errors:
ValidationErrors errors = ctx.getActionBeanContext().getValidationErrors();
errors.add(someError.getFieldName(), someError);
(The salient difference to the ErrorMessageInterceptor is that you put each error you get out of the list (which you put in there in the validation error handler) in the regular validation errors, not global errors. This allows them to retain the field they are related to.)
Related
The code base I am working with is spring and jersey.
I am on this new code base, and within the 500 exceptions got back from REST call in response.context.entityContent, I found that the RO containing the true exception is a ByteArrayInputStream.
Right now I can extract the server exception message with ex.getResponse().readEntity(CustomRO.class).getMessage().
The 500 exceptions containing the RO, however, does not contain the cause (ex.getCause() = null).
Is there a way I can apply read Entity to all exceptions on the client side, get the exception in the RO and put it as the cause of the 500 InternalServerErrorException?
Please correct me if I am wrong in any of my thoughts, and let me know if there is any standard that I should follow.
Also it is my first time asking here, so I am sorry if my wording is long or not to the point
I am currently using java and spring boot to get authorized in a API. It depends on the value that users inserts to see weather the api is valid or not.If it's valid it would basically display data.
Main Problem
When user enters wrong value in the end of the api. I get error 500 "internal server error" and it stops my spring application. I want to create an exception where it would catch this error and spits out that there's an error 500 rather than stopping my application. Even with wrong value I want my application to continue running.
Error
When users enter the wrong params I receive an error below
org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
How can I override it, so that even if user enter wrong data, Don't break my application and continue running. Just display Null for data.
Attempt to handle
I was able to allow my application to continue running with following code below
try { //OauthRestTemplate exhanges credentials for api access
} catch (HttpServerErrorException e ) {
e.getStatusCode();
logger.info(e + "Server bypass, Continue running application");
//allow application to continue running but does not display the actual message that would be on the api.
}
//output
org.springframework.web.client.HttpServerErrorException: 500 Internal Server ErrorServer bypass, Continue running application
But I want it to by pass the status 500 and display the actual message when I am on the api with wrong parameters. I should receive the same values that are printed on the api. Example Below
{"message":"Physical resource does not exist for mac address: D","code":"APRO-2001","timestamp":1490895756655,"type":"com.server.camp.framework.exception.ErrorResponse","status":"INTERNAL_SERVER_ERROR"}
I don't know if this applies to your problem (as you did not provide your code yet) but this might help:
#ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No such Order") // 404
public class OrderNotFoundException extends RuntimeException {
// ...
}
You can basically add the #ResponseStatus to a function inside your class, set the value to the appropriate one (in your case INTERNAL_SERVER_ERROR as shown here).
I hope this helps! If not, please provide your code.
Maybe this link about Exception-Handling in spring might help: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
I am trying to implement a process consisting of several webservice-calls, initiated by a JMS-message read by Spring-integration. Since there are no transactions across these WS-calls, I would like to keep track of how far my process has gone, so that steps that are already carried out are skipped when retrying message processing.
Example steps:
Retrieve A (get A.id)
Create new B for A (using A.id, getting B.id)
Create new C for B (using B.id, getting C.id)
Now, if the first attempt fails in step 3, I already have a created a B, and know it's id. So if I want to retry the message, it will skip the second step, and not leave me with an incomplete B.
So, to the question: Is it possible to decorate a JMS-message read by Spring-integration with additional header properties upon message processing failures? If so, how could I do this?
The way it works at the moment:
Message is read
Some exception is thrown
Message processing halts, and ActiveMQ places the message on DLQ
How I would like it to work:
Message is read
Some exception is thrown
The exception is handled, with the result of this handling being an extra header property added to the original message
ActiveMQ places the message on DLQ
One thing that might achieve this is the following:
Read the message
Start processing, wrapped in try-catch
On exception, get the extra information from the exception, create a new message based on the original one, add extra info to header and send it directly to the DLQ
Swallow the exception so the original message dissappears
This feels kinda hackish though, hopefully there is a more elegant solution.
It's hard to generalize without more information about your flow(s) but you could consider adding a custom request handler advice to decorate and/or re-route failed messages. See Adding Behavior to Endpoints.
As the other answer says, you can't modify the message but you can build a new one from it.
EDIT:
So, to the question: Is it possible to decorate a JMS-message read by Spring-integration with additional header properties upon message processing failures? If so, how could I do this?
Ahhh... now I think I know what you are asking; no, you can't "decorate" the existing message; you can republish it with additional headers instead of throwing an exception.
You can republish in the advice, or in the error flow.
It might seem like a "hack" to you, but the JMS API provides no mechanism to do what you want.
From the spring forum:
To place new header to the MessageHeaders you should use
MessageBuilder, because not only headers, but entire Message is
immutable.
return MessageBuilder.fromMessage(message).setHeader(updateflag, message.getHeaders().get("Lgg_Rid") == "ACK" ? "CONF" : "FAIL").build();
In an asynchronous context, errors will go to an error channel - either one you configure yourself and indicate in the message headers with errorChannel, or a global error channel if none is specified. See for more details here.
I have an init method on my #ViewScoped mananged bean. In the post construct i load data from the db. I have a custom ExceptionHandlerWrapper to catch all excptions and send to an error pages. However when #PostConstuct throws an exception i recieve an IllegalStateException and am not redirected to the error page. I have tried many combinations.....
Ive tried this inside my ExcpetionHandler
externalContext.getRequestMap().put(ERROR_BEAN_ID, ERROR_TEXT);
externalContext.dispatch(ERROR_PAGE);
fc.responseComplete();
This line below is what i originally had. It also doent work
externalContext.getFlash().put(ERROR_BEAN_ID, ERROR_TEXT);
nav.handleNavigation(fc, null, ERROR_PAGE);
fc.renderResponse();
These all cause IllegalStateExceptions. I also called redirect with the same result.
Can you globally catch errors thrown from #PostConstruct?
These all cause IllegalStateExceptions.
With the message "Response already committed", I assume? Well, that's a point of no return. A part of the response has already been sent to the client (the webbrowser). It's not possible to take the already sent bytes back. The server will end up with this exception in the logs and the client will end up with a halfbaked response.
What can you do?
Most straightforward way would be to enlarge the response buffer size to the size of the largest page. For example, 64KB:
<context-param>
<param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
<param-value>65536</param-value>
</context-param>
It defaults to ~2KB depending on the server configuration. You only need to keep in mind that this may be memory hogging when your server has to process relatively a lot of requests/responses. Profile and measure properly.
Another way is to reference the bean before the response is to be rendered/committed so that it's (post)construction is triggered before that point. Perhaps the bean in question is referenced for the first time at the very bottom of the view, long beyond the ~2KB response size border. You could take over the job of #PostConstruct with a <f:event type="preRenderView"> somewhere in the top of the view. E.g.
<f:event type="preRenderView" listener="#{bean.init}" />
with
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
// Do here your original #PostConstruct job.
}
}
I've already looked for the answer for this question, and I've found the following suggestions:
If you are always expecting to find a value then throw the exception if it is missing. The exception would mean that there was a problem. If the value can be missing or present and both are valid for the application logic then return a null.
Only throw an exception if it is truly an error. If it is expected behavior for the object to not exist, return the null.
But how should I interpret them in my (so casual) case:
My web app controller is receiving request to show details for a user with a certain id. Controller asks the service layer to get the user, and then the service returns the object, if it's found. If not, a redirect to 'default' location is issued.
What should I do when someone passes invalid user id inside the request URL? Should I consider it as "expected behaviour" and return null to the controller, or perhaps should I call it a "problem or unexpected behaviour" and thus throw an exception inside the service method and catch in inside the controller?
Technically it's not a big difference after all, but I'd like to do it the right way by following standard convetions. Thanks in advance for any suggestions.
EDIT:
I assume, that the URLs generated by the app are valid and existing - when clicked by user, the user with a certaing id should be found. I want to know how to handle a situation, when user tries to access URL with wrong (not existing) user id, by manually typing the URL into browser's address bar.
If I understand you correctly, the request containing the user ID is coming from a client (out of your control). Applying the rules of thumb you quoted: invalid user input is an entirely expectable case, which would not require an exception, rather handle the null value gracefully by returning an appropriate error message to the client.
(OTOH if the user id in the request were automatically generated by another app / coming from DB etc, an invalid user ID would be unexpected, thus an exception would be appropriate.)
My personal suggestion would be to log the error details (IP address, the invalid user ID) and re-direct the user to an error page which says that some error has occurred and the administrators have been notified. Click on so-n-so link to go back to your home page etc.
Point being, whether you throw exception or return null, just make sure that the outermost filter or handler "logs" the details before the response is returned to the user.
What should I do when someone passes invalid user id inside the request URL?
You have two choices: show the 'default' page you mentioned or return a "Not found" / 404.
Regarding null, it depends. If you consider null unacceptable for a reference, then annotate it with #NotNull and the annotation shall take care of doing the correct thing upon getting a null reference: that is, throwing an (unchecked) exception (of course you need to work with the amazing #NotNull annotation for this to work).
What your do higher up the chain is up to you: to me returning a 404 to someone trying to fake user IDs sounds really close to optimal.