0

I have a method handleException that return a ResponseEntity :


@ExceptionHandler({Exception.class})
public ResponseEntity handleException(Exception e) {
    Map<String, String> data = new HashMap<>( );
    List temp;
    data.put( "message", e.getMessage() );
    if (e instanceof MissingServletRequestParameterException) {
        if ( e.getMessage().contains("countryName") )
        {
            temp = REP_MAP.get(Utility.HttpCode.REP_HTTP_CNABSENT);
        } else{
            temp = REP_MAP.get(Utility.HttpCode.REP_HTTP_DTABSENT);
        }
        data.clear();
        data.put( "message",  (String)temp.get(1));
        return ResponseEntity.status((HttpStatus)temp.get(0)).body( data);
    } else if (e instanceof CustomException) {
        return ResponseEntity.status(((CustomException) e).getStatus()).body(data);
    }
    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(data);
}

and it was working fine before adding loggingInterceptor :

@Around("execution(*  com.coviddata..*(..) )")
public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {
    Object temp = null;
    String inputString = getInput(joinPoint);
    logger.debug(inputString);
    try{
        temp = joinPoint.proceed();
    }
    catch (Exception e) {
        logger.error( ERROR  + "  " + ((MethodSignature)joinPoint.getSignature()).getDeclaringTypeName() + " " + joinPoint.getSignature().getName() );
    }
    finally {
        logger.debug( OUT  + ((MethodSignature)joinPoint.getSignature()).getReturnType() );
        return temp;
    }
}

Now, i can log before and after of all methods. the problem is when an exception is thrown, this log method prevent my exception handler to be called and thus nothing is send to the user as ResponseENtity and even the joinPoin.proceed() return null.

I have tought to intercept all methods except handleException but I think this is not the problem. I think the solution of that. I want only to log when there is exception and return ResponseEntity.

Is there a way to exclude handleException method from being intercepted ?

khalid tounoussi
  • 499
  • 5
  • 21
  • 2
    You are catching and swallowing the exception, what else would you expect? You shouldn't catch and swallow. You should at least do a `throw e` in your `catch` clause else processing will stop. – M. Deinum Dec 15 '22 at 12:37
  • I have add throw e, but still the exceptionHandler is not called. its like with finally block send null answer and nothing is showing in browser. – khalid tounoussi Dec 15 '22 at 12:41
  • Then there must be something else as well, however you should never swallow exceptions in an around aspect (unless you are writing a specific aspect for that). – M. Deinum Dec 15 '22 at 12:43
  • 2
    a `return` inside a `finally` block is calling for problems (at least an unexpected behavior for some developers) - the `finally` block is always executed, so even if (re-)throwing the Exception, the `return` statement will be executed and *override* (or *cancel*) the exception – user16320675 Dec 15 '22 at 12:54
  • 1
    actually it IS expected behavior according [JLS 14.20.2. Execution of try-finally and try-catch-finally](https://docs.oracle.com/javase/specs/jls/se19/html/jls-14.html#jls-14.20.2-100-B-A-B-B): "*If the catch block completes abruptly for reason R, then the finally block is executed. Then there is a choice: ... If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded)*" (a `return` is also one reason for terminating the method abruptly) – user16320675 Dec 15 '22 at 12:59
  • I have changed the signature of log method to void and removed return statement. and what happened is that my handleException is called( shown in log ) but as long as I have removed return statement nothing is shown in navigator. – khalid tounoussi Dec 15 '22 at 14:17
  • I think the solution is to exclude the method handleException, is there any way to exclude it from being intercepted ? – khalid tounoussi Dec 15 '22 at 14:43

1 Answers1

0

I have first exclude the method handleException annotated with @ExceptionHandler as the following :

 @Around("execution(*  com.coviddata..*(..) )"
            + "&& !@annotation( org.springframework.web.bind.annotation.ExceptionHandler)")

I have added a flag that is been set to true when there is an exception, adding a return null at the end of the method ( not in finally) solve the problem, I dont know why :

 @Around("execution(*  com.coviddata..*(..) )"
            + "&& !@annotation( org.springframework.web.bind.annotation.ExceptionHandler)")
 public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Object temp = null;
        String inputString = getInput(joinPoint);
        logger.debug(inputString);
        boolean flag = false;
        try{
            temp = joinPoint.proceed();
        }
        catch (Exception e) {
            flag = true;
            logger.error( ERROR  + "  " + ((MethodSignature)joinPoint.getSignature()).getDeclaringTypeName() + " " + joinPoint.getSignature().getName() );
            throw e;
        }
        finally {
            logger.debug( OUT  + ((MethodSignature)joinPoint.getSignature()).getReturnType() );
            if(! flag)
                return temp;
        }
        return null;
    }
khalid tounoussi
  • 499
  • 5
  • 21
  • 1
    This code is just wrong. Like someone else already said before, **do not try to return values from a `finally` block!** – kriegaex Dec 16 '22 at 14:14
  • Normally finally is called either an exception is thrown or not. and my method except an Object, so it is normal to add a return in finally block. – khalid tounoussi Dec 16 '22 at 15:44
  • No, it is not. With all due respect, stop talking nonsense. Better learn how to canonically use try-catch-finally. Even if it is technically possible to put a return statement in a finally block, why are you so stubborn to defend bad code design and even risk problems, if there is a very simple, less contrived solution for your problem? Why would you throw an exception in the catch block and override same in finally? – kriegaex Dec 16 '22 at 16:22