I can't seem to find proper solution to this. I would want to handle and display different message to the user depending on what happened. I'm using Spring WS and calling marshalSendAndReceive. On the returning service method at the moment I would simply catch (WebServiceIOException e), problem is that this exception is thrown by both Connection refused (wrong credentials) and when query takes longer than specified by client side (timeout)? Is there any proper way of handling these two without providing one general message that "something went wrong".
The WebServiceTemplate does its hard work in the method doSendAndReceive, where there is try...catch block and comprehensive error-handling. One of them is triggerAfterCompletion(int interceptorIndex, MessageContext messageContext, Exception ex), which delegates to the injected ClientInterceptor.
So, you just need to implement properly afterCompletion(MessageContext messageContext, Exception ex) to throw the appropriate business exception.
One way is to implement ClientInterception class
Another way is just catching general Exception class on where you send a request to web serice:
try {
webServiceTemplate.marshalSendAndReceive(request);
} catch(Exception e){
log.error("your custom message");
}
Related
I am new to Axon framework and am trying to implement an application using CQRS with state-stored aggregates. The application relies on a database constraint (using H2 for now) to enforce uniqueness on a name attribute. I would like to catch this exception and rethrow it as a user-friendly domain exception.
Per the Axon documentation:
Exception Handling says "an #ExceptionHandler will only handle exceptions thrown from message handling functions in the same class"
Message Intercepting documentation says "A function annotated with #ExceptionHandler will be regarded as a handler interceptor which will only be invoked for exceptional results. Using annotated functions to this end for example allow you to throw a more domain specific exception as a result of a thrown database/service exception."
But I cannot get this to work. I have tried adding exception handlers as follows:
#ExceptionHandler
public void handle(ConstraintViolationException ex) throws Exception {
if (ex.getMessage().contains("UNQ_COMPANY_ID") || ex.getMessage().contains("UNQ_PLAN_NAME")) {
throw new DomainException("Plan name and company id must be unique");
}
throw ex;
}
but this method is not called. I have tried putting the exception handler method on the aggregate and on a separate command handler class, tried adding resultType=ConstraintViolationException.class, and tried catching other types of exceptions including Exception, RuntimeException, AxonServerRemoteCommandHandlingException, etc. but this method is never called.
I can see the error in the log output:
org.axonframework.axonserver.connector.command.AxonServerRemoteCommandHandlingException: An exception was thrown by the remote message handling component: org.hibernate.exception.ConstraintViolationException: could not execute statement
Is it possible to catch database exceptions in state-stored aggregates? If it is, can someone point me towards what I am doing wrong?
The statement "an #ExceptionHandler will only handle exceptions thrown from message handling functions in the same class" makes me wonder whether I need to create a custom repository class (rather than using the default GenericJpaRepository) but that seems like a lot more work than should be necessary.
Thank you!
Update: I was able to roughly accomplish what I want by adding a UnitOfWork parameter to the #CommandHandler method and using it to registering a rollback callback on it as follows:
uow.onRollback(unit -> {
DefaultUnitOfWork duow = (DefaultUnitOfWork) unit;
Throwable ex = duow.getExecutionResult().getExceptionResult();
while (ex != null) {
if (ex.getMessage().contains("UNQ_PLAN_NAME")) {
throw new RuntimeException("Plan name must be unique");
}
ex = ex.getCause();
}
});
But this seems kind of verbose, as well as limiting me to throwing unchecked exceptions only. This also doesn't feel like the right way to do this though because I assume the purpose of the #ExceptionHandler annotation is to eliminate need for code like the above.
This is doable of course.
Actually, the best pointer I could give you if the code-samples repo where you can see a sample about distributed exceptions.
In general, as you could see in your shared log, the 'original' exception is wrapped into an AxonServerRemoteCommandHandlingException meaning you will have to handle that. Doing that, you can pretty much add anything to the details field of this class, adding the indication you had a ConstraintViolationException for example (or an ERROR_CODE, like HTTP protocol does) and you are fine to unwrap it on the other side.
What might be the "gotcha" you require, is to know that an #ExceptionHandler annotated method should reside in the object handling the message. So if you want to react to a failing command handling operation (which would be the case in your sample), you will need to place the exception handler in the Aggregate, next to the Command Handler.
That fact you get an AxonServerRemoteCommandHandlingException to me suggests the exception is caught on the command dispatching end. So, prior to dispatching a command on the CommandGateway/CommandBus.
However, whether this is the problem at hand, isn't clear to me right now, since the sample only shows the exception handler and not where it resides. Please share whether my assumption on the placement of the exception handler is correct. If not, we'll dive into this deeper to get to the cause.
I am developing a restful webservices using java. I am handling all runtime and other possible exception scenarios to send meaningful response to client.
When something like out of memory occurs, how do i make sure client gets meaningful response from the server?
Am using CXF and ExceptionMapper.
In Spring, you can catch your exceptions and map them to meaningful HTTP status codes. Following code might work for you (maps YourException to HTTP 500):
#ControllerAdvice
public class ExceptionProcessor {
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
#ExceptionHandler({YourException.class})
public void serverError(HttpServletRequest req, Exception exception) {
// ...
// Print exception to server log
exception.printStackTrace();
}
}
It's not an exception; it's an error: java.lang.OutOfMemoryError
You can catch it as it descends from Throwable:
try {
// create lots of objects here and stash them somewhere
} catch (OutOfMemoryError E) {
// release some (all) of the above objects
}
However, unless you're doing some rather specific stuff (allocating tons of things within a specific code section, for example) you likely won't be able to catch it as you won't know where it's going to be thrown from.
If the root cause of your problem is a memory leak, then the chances are that catching and recovering from the OOM will not reclaim the leaked memory. You application will keep going for a bit then OOM again, and again, and again at ever reducing intervals.
There is probably at least one good time to catch an OutOfMemoryError, when you are specifically allocating something that might be way too big:
I'm using HandlerExceptionResolver for this:
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
#Override
#ExceptionHandler(value = Exception.class)
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
Your error processing goes here
}
}
So every exception, goes in resolveException, and I write appropriate message (In my case JSON) to the response.
There is also a good article http://www.journaldev.com/2651/spring-mvc-exception-handling-exceptionhandler-controlleradvice-handlerexceptionresolver-json-response-example
The problem with OutOfMemoryError is that it may happen in any thread, including threads that do not run your REST services code. In a server context, it is considered a bad practice to catch any Error. You should let it bubble up the call stack to be handled by the server code.
Instead of catching it, it would be better to investigate why you run out of memory and fix the cause. It could be that your server simply doesn't have enough memory allocated, or that you have a memory leak somewhere. You need to analyze the problem, for instance by analyzing the resulting heap dump(s), and ensure that it doesn't happen anymore.
In a managed environemnt like a Java EE server, it is dangerous and generally fallacious to assume you can recover from OutOfMemeoryError by catching it. Most often, you can't even catch it because it happens in a thread you don't control.
I have an application which consists of SOAP and REST web services and a simple HTTP access. All of them convert incoming requests and send them to a handler. The most painful thing is exception handling. In order to return the right response, I have to wrap every method with try-catch block and create a response there.
I thought that I could create a filter which could do it. But how can the filter recognise the source of it (soap, rest frontend) so I knew that I should return a SOAP or other response?
It depends on the WS framework you use. All I know have some sort of interceptors/aspects that you can inject and handle exceptions in one place. For instance in apache-cxf there is even a special outbound error chain where you can plug your own interceptors.
Obviously try-catch in every method is a bad idea.
In layer of below Web-Service Layer, you have to create your custom Exception and in Web-Service layer you have to use try-catch approach for achieve occurred exception and in catch block log and convert it to your custom web service layer exception. I show this approach in following:
#WebService
public class EmployeeWS
{
#WebMethod
public void add(Employee em) throws CustomWebServiceException
{
try
{
// call facade layer method
}
catch(Exception e)
{
logger.error(e.getMessage());
throw new CustomWebServiceException(e);
}
}
}
Alternative using try catch in any Web-Method,you can use AOP approch(for sample Spring AOP) or interceptor approach in Web-Service frameworks(for sample SOAPHandler<T> in JAX-WS).
Note: In JAX-WS standard, you can't throw a RuntimeException because Exception must specify in final WSDL and if you throw a RuntimeException your web service client don't achieve your CustomException, in another your Web-Methodneed to throws in itself signature.
You can see selected Web-Service faramework documents for more information.
It sounds that you are not using any framework because that was typical frameworks provide. For example Spring allows you to decouple the code from exception handling and define your custom exception handlers.
In your case you generally have 2 solutions.
(1) You can use Decorator pattern: wrap each service with decorator where each method is implemented as
try {
call real method
} catch() {
send error to client
}
Since it is very verbose you can save time using Dynamic proxy (feature that was introduced in java 5). So, you can dynamically wrap each service (if your services have defined interface).
(2) You can solve it using servlet API's error page:
javax.servlet.ServletException
/servlet/ErrorDisplay
for more details see http://java.sun.com/developer/technicalArticles/Servlets/servletapi2.3/
You can customize your class!! Do it!
Take easy on diagnostic errors, like insert a protocol number, message Log, message client, etc...
http://java.globinch.com/enterprise-java/web-services/jax-ws/jax-ws-exceptions-faults-annotation-exception-and-fault-handling-examples/#Pre-Requisites
My Spring MVC app is full of methods that look like this:
#RequestMapping(value = "/foo", method = RequestMethod.GET)
public final void foo(HttpServletRequest request, ModelMap modelMap){
try{
this.fooService.foo();
}
catch (Exception e){
log.warn(e.getMessage(), e);
}
}
Exceptions are caught and logged but not handled otherwise.
The fooService called above does the same thing, never throwing exceptions up to the controller but catching and logging them. So, actually this controller exception code will never get invoked.
What's the best and simplest approach to implement proper exception handling in my app?
Get rid of all catch statements if all they do is logging carelessly. catch is meant to handle the error, not hide it.
Once all these catches are removed, install one global exception resolver in Spring MVC (1, 2, 3, ...) Simply implement this trivial interface:
public interface HandlerExceptionResolver {
ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}
In your exception resolver you might simply log the exception once and let it go as unprocessed (return null), so that error mappings in web.xml will forward request to proper error page. Or you can handle exception yourself and render some error page. AFAIK in simplest case there is no need for register exception resolver, just define it as a Spring bean/annotate with #Service.
Remember, catch the exception only when you know what to do with. Logging is only for troubleshooting, it doesn't handle anything.
BTW this:
log.warn(e.getMessage(), e);
is not only a very poor exception handling, but it is also slightly incorrect. If your exception does not have a message, you will see mysterious null just before the stack trace. If it does, the message will appear twice (tested with Logback):
22:51:23.985 WARN [main][Foo] OMG! - this is the exception message
java.lang.IllegalStateException: OMG! - this is the exception message
at Foo.bar(Foo.java:20) ~[test-classes/:na]
...sometimes undesirable, especially when exception message is very long.
UPDATE: When writing your own exception logger consider implementing both org.springframework.web.servlet.HandlerExceptionResolver and org.springframework.core.Ordered. The getOrder() should return something small (like 0) so that your handler takes precedence over built-in handlers.
It just happened to me that org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver running prior to my handler returned HTTP 500 without logging the exception.
I want to use an interceptor for my bean, which will check the validity of a given connection token.
If the connection is invalid, I want to throw a particular exception, if the connection expired, I want to send another (TokenExpiredException, something like this). These Exceptions are included in the interface given to the client.
#AroundInvoke
public Object checkParams(InvocationContext ctx) throws TokenExpiredException, Exception{
//code to check token
//...
throw new TokenExpiredException();
}
From what I tried, throwing such specific Exception in the Interceptor leads to an UndeclaredThrowableException on the client side. While this exception includes the reference to the cause, it is not really ideal, and can't be dealt with with regular catch clauses.
What is the correct way then to declare different Exception types with Interceptors?
I don't think there is a correct way to do that. Methods should throw only the exceptions they declared, and an interceptor shouldn't add a new one.
My personal case got fixed by adding an error code to our default exception which is thrown by all methods.