if the exceptions have been swallowed, how does the spring aop log the exceptions' messages? - spring

Here is my example bellow
public void test() throws Exception {
try {
int i = 1/0;
System.out.println(i);
} catch (Exception e) {
//the exception have been swallowed.
}
}
and the problem is spring aop's AfterThrowing can't work for this. if i remove the try-catch block.it works well then. how can i solve this problem. thanks for any suggestions.

Although it's unclear from question what you intend to achieve but this is the intended behavior of #AfterThrowing advice.
From docs -
After throwing advice runs when a matched method execution exits by throwing an exception.
which means that the advice will be executed only if an exception is thrown from method. In your sample the the exception is consumed and method exits normally thus no advice execution occurs.

Related

Spring Boot logging - Don't log ConstraintViolationExceptions

Here's my problem. I call a service method in the controller which is annotated with #Transactional. If this is comitted, a ConstraintViolationException occurs. I would like to catch it and put it into my own exception. Now I have the problem that I can catch the TransactionSystemException, but an error has already been logged. Can I prevent this somehow?
public ResponseEntity<T> update(String id, T obj) {
try {
return getResponseEntity(service.update(id, obj));
} catch (TransactionSystemException ex) {
System.out.println("CATCHED");
throw new InternalErrorException();
}
}
During my research I found out that I can disable logging for certain packages like
logging.level.org.springframework.dao.DataIntegrityViolationException=OFF
or
logging.level.org.hibernate.TransactionException=OFF
But that didn't help and I don't want to disable logging completely with logging.level.org.hibernate=OFF.
Please try to use #ControllerAdvice.
https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
https://medium.com/#jovannypcg/understanding-springs-controlleradvice-cd96a364033f

Handling exceptions in Spring MVC along with Rest API

I am using #ControllerAdvice annotation for defining exceptions at application level. Now the problem is I am having two #ControllerAdvice classes, one for REST and one for the normal web app. When I define #ExceptionHandler for Exception.class in both, only the first one is considered. How do I separate both? Or how can I catch an Exception and determine from where it has occured? Is there a way or else do I need to use controller-specific exception handlers?
I resolved this issue by creating a custom exceptions for my application and giving one exception handler method for each of them with #exception handler.
I also used aspects to make sure that every exception is converted to any of the custom exceptions.
#Aspect
#Component
public class ExceptionInterceptor {
#AfterThrowing(pointcut = "within(x.y.package..*)", throwing = "t")
public void toRuntimeException(Throwable t)
throws ApplicationException1, ApplicationException2,ApplicationException3 {
if (t instanceof ApplicationException1) {
throw (ApplicationException1) t;
} else if (t instanceof ApplicationException2) {
throw (ApplicationException2) t;
} else
throw (ApplicationException3) t;
}
}
These will transfer control to #controlleradvice.
I noticed this have been left for a month or so, so it might be old. But this article may help http://www.baeldung.com/2013/01/31/exception-handling-for-rest-with-spring-3-2/.
The section 3.5 is probably what you are looking for, a custom Exception Resolver.

Using Spring AOP, How can I intercept a exception just when it occurred?

Some code like this:
public class A {
#Autoware
private B b;
public void a() {
//AAA: some logic process that maybe throw exception
b.b();
}
}
public class B {
public void b() {
//BBB: some logic process maybe also throw exception
}
}
Both exceptions in A.a() and B.b() need to be intercept, so i use #AfterThrowing annotation do it. but the question is, when i call A.a() in other code and exception has occurred in B.b(), the Advice will execute twice! because exception that occurred in B.b() was propagating to its caller A.a().
I can't swallow the exception silently, because i use spring-amqp, above codes is on Consumer side, i need some message processing that based on the exceptions that occurred in Consumer.
#Around does not work too since i can't swallow the throwed exception.
So, How can i intercept a exception just when it occurred? ignore propagation of it.
Any reply is greatly appreciated.

How to capture Sybase RAISERROR in Mybatis-Spring?

I am trying to capture error messages in my Java code from stored procedures in Sybase using RAISERROR, but nothing is being caught, even though when I call the proc directly I can see the error is thrown.
I understand that Mybatis-Spring
translates MyBatis exceptions into Spring DataAccessException
So I have coded my Mapper class thusly:
void insertData(Data toInsert) throws Exception, DataAccessException;
I'm trying to catch both of these exceptions, but nothing is caught.
Does anyone have any ideas?
Thanks,
Stephen
I found out how to do it:
try {
myMapper.insertData(data);
}
catch (org.springframework.jdbc.UncategorizedSQLException e) {
Throwable ee = use.getCause();
// getMessage on chained exception gets message from RAISERROR
log.error(ee.getMessage(), e);
}
Cheers,
Stephen

Spring, Aspect J, multiple AfterThrowing advice applied to the same pointcut

Is it possible to have two AfterThrows pieces of advice be applied to the same pointcut restricted by specific Exception type where one exception is a superclass of the other with, in the case of the subclass being captured, only one advice being executed?
I want to translate runtime exceptions (both custom and standard java ones) being chucked out of a service layer, where I do some specific translation in certain cases and then have a catch-all type piece of advice to translate anything truly unexpected:
#AfterThrowing(pointcut = "execution(* com.my.company.api.*(..))", throwing = "rnfex")
public void doTranslationAction(ResourceNotFoundException rnfex) {
// throw new WebApplicationException with Status.NOT_FOUND;
}
#AfterThrowing(pointcut = "execution(* com.my.company.api.*(..))", throwing = "aex")
public void doTranslationAction(AuthorisationException aex) {
// throw new WebApplicationException with Status.NOT_AUTHORISED;
}
#AfterThrowing(pointcut = "execution(* com.my.company.api.*(..))", throwing = "throwable")
public void doTranslationAction(Throwable throwable) {
// Log something here about this unexpected exception
// throw new WebApplicationException with Status.INTERNAL_SERVER_ERROR
}
I find that in this case, if I throw an exception which is explicitly catered for then the correct method is called, a translated exception is thrown, which is then captured by the broader 'Throwable' advice, then translated again into the catch-all INTERNAL_SERVER_ERROR WAE. This isn't unexpected, but just not quite what I was looking for.
To get around this I've got a single piece of advice which captures all Throwable types and then uses 'instanceof' to decide whether this is an expected custom runtime exception that I can translate into a specific WAE or not.
If I ever see 'instanceof' I'm sure I've done something to be ashamed of, but I'm not sure if there's a better way of solving this problemette without it?
I'm also against converting my expected custom exceptions to checked exceptions and then catching Runtime exception as the catch all, which could be one solution.
I wrote a similar aspect a while ago and I ended up using "instance of". I don't think there's a problem with that.
i am not pretty sure... but just wondering whether your last(third) advice can be written in the below fashion
execution( * com.my.company.api..*(..)) and !execution( * com.my.company.api.XyzAspect..*(..))
public void doTranslationAction(Throwable throwable) {
// Log something here about this unexpected exception
// throw new WebApplicationException with Status.INTERNAL_SERVER_ERROR
}
where XyzAspect.java is the #Aspect class where in you are writing these 3 advices.

Resources