5

If an exception should be ignored inside a method call, one would write eg the following:

public void addEntryIfPresent(String key, Dto dto) {
   try {
        Map<String, Object> row = database.queryForMap(key);
        dto.entry.put(row);
   } catch (EmptyResultDataAccessException e) {}
}

I'm trying to write eg a custom spring annotation that has the same effect, but could just be applied to the method header. That could look similar to the following:

@IgnoreException(EmptyResultDataAccessException.class) //this annotation does not exist
public void addEntryIfPresent(String key, Dto dto) {
   Map<String, Object> row = database.queryForMap(key);
   dto.entry.put(row);
}

How could such an annotation be created?

membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • You can refer to this link, I find it useful. [enter link description here](https://stackoverflow.com/questions/19389808/using-annotations-for-exception-handling) – Duega Oct 22 '18 at 08:01
  • You can use AOP, if I'm not mistaken, on what to do when an Exception is thrown. Just to give a thought: https://dzone.com/articles/handling-exceptions-using-springs-aop – Stultuske Oct 22 '18 at 08:06
  • Afaik one has to explicit define the package+classname in an `AOP pointcut` catcher. I'd rather like to create an annotation that can by applied to any method, thus is defined generic.... – membersound Oct 22 '18 at 08:09
  • Just curious: what would your client code look like if you ignore exceptions such as this one? This could lead to increased complexity for callees when you're not sure if there is a result or not. – Mick Mnemonic Oct 22 '18 at 08:11
  • @membersound nope. the package and classname that needs to be put in the pointcut, is that of the annotation. I once wrote a small library containing all the configuration of aop. All I needed to do later on, was just add the annotation I wanted on the method I wanted it on, and to provide an implementation in case I chose not to use the default one I had provided in the library – Stultuske Oct 22 '18 at 08:11

1 Answers1

4

Here is a way of doing it with AspectJ.

First of all, define a method level annotation.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface IgnoreRuntimeException{

}

Then, define an around aspect for the annotation.

@Component
@Aspect
public class ExceptionHandlingAdvice {

    @Around("@annotation(com.yourpackage.IgnoreRuntimeException) && execution(* *(..))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        Object returnObject = null;
        // do something before the invocation
        try {
            // invoke method
            returnObject = joinPoint.proceed();
            // do something with the returned object
            return returnObject;
        } catch (Exception e) {
            // do something with the exception
        }
    }

}

You can then apply the annotation on top of your methods to ignore exceptions.

@IgnoreRuntimeException
public void addEntryIfPresent(String key, Dto dto) {
    // ...
}

You can also check the parameters of the annotation using the api of ProceedingJoinPoint to ignore only the exceptions that you'd like to ignore.

Krzysztof Cichocki
  • 6,294
  • 1
  • 16
  • 32
  • Since database.queryForMap(key) throws EmptyResultDataAccessException which I assume is a checked exception, I don't think the code would compile. –  Oct 22 '18 at 08:18
  • @aka-one https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/dao/EmptyResultDataAccessException.html –  Oct 22 '18 at 08:20
  • @aka-one if it was a checked exception, the `addEntryIfPresent` method from OPs example would not compile. –  Oct 22 '18 at 08:22
  • Ok, but what if in addEntryIfPresent body I call a method that throws an unchecked exception? I want to point out your code works only for unchecked exceptions. –  Oct 22 '18 at 08:22
  • Then the `addEntryIfPresent` in its current form would no longer compile. –  Oct 22 '18 at 08:24
  • It is possible to pass the classtype of the to be ignored exception as an argument to the annotation? Cause I want to ignore a specific exception on one method, and for the next method I'd might want to ignore a different exception. It would not be handy if I'd have to create a concrete annotation for each ignore-case. – membersound Oct 22 '18 at 08:49
  • @membersound This should help you with that https://stackoverflow.com/questions/21275819/how-to-get-a-methods-annotation-value-from-a-proceedingjoinpoint –  Oct 22 '18 at 08:55