0

I have two different Aspect Classes, aspect class 1 would take care of any exceptions that would occur in all of my controller files and the other, aspect class 2, would handle few specific exceptions that would occur only in one specific controller file. I have specified the precedence order, giving aspect class 2 higher precedence over aspect1. Aspect class 1 is as below

@Aspect
@Order(1)
public class TrackOperations {
@Around("apiPointcut()")
public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
    try {
        return pjp.proceed();
    } catch (Exception e) {
        LOGGER.error("Caught exception: ", e);
        StringBuilder sb = getExceptionTrace(e);
        StringWriter errorStackTrace = new StringWriter();
        e.printStackTrace(new PrintWriter(errorStackTrace, true));
        response.addError(error);
        return new ResponseEntity<String>(JsonUtil.toJson(response), HttpStatus.INTERNAL_SERVER_ERROR);
    }} 

Aspect class 2

@Aspect
@Order(0)
public class TrackServiceOperations {
@Around("apiPointcut()")
public Object handleServerException(
    try {
        return pjp.proceed();

    } catch (HttpClientErrorException | HttpServerErrorException e) {
        response = (Response<String>) ContextUtil.get(key);
        response.addError(new Error("Assessment Service Status Code: " + e.getStatusCode(), ErrorConstants.REQUEST_FAILED));
        LOGGER.error("Recieved" + e.getStatusCode() + " status from Assessment Service");
        return new ResponseEntity<String>(JsonUtil.toJson(response), HttpStatus.OK);
    }
}}

Have mentioned the same in the application xml

<bean    id="TrackServiceOperations" class="in.foo.foo.TrackServiceOperations" factory-method="aspectOf" />
<bean   id="TrackOperations" class="in.foo.foo.TrackOperations" factory-method="aspectOf" />

But when the controller file throws the desired exception, aspect class 1 ends up handling the exception instead of aspect class 2. When I disable aspect class 1 things work out fine as expected, but when I use both the @around pointcuts, the precedence order doesn't seem to work. Am I missing something here?

Crane
  • 121
  • 2
  • 9

2 Answers2

1

aspect class 1 is handling the generic Exception which both HttpClientErrorException and HttpServerErrorException derive from. So by the time you want the exceptions handled in aspect class 2 they've already been covered by aspect class 1's handler.

To fix you could examine the type of exception in the aspect class 1 handler and rethrow those special exceptions you want handled in aspect class 2. (This feels like a kludge, since it now has aspect 1 knowing about the contents of aspect 2).

public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
try {
    return pjp.proceed();
} catch (Exception e) {
    (if e instance of org.springframework.web.client.HttpStatusCodeException || e instanceof org.springframework.web.client. HttpServerErrorException) throw e;

    LOGGER.error("Caught exception: ", e);
    StringBuilder sb = getExceptionTrace(e);
    StringWriter errorStackTrace = new StringWriter();
    e.printStackTrace(new PrintWriter(errorStackTrace, true));
    response.addError(error);
    return new ResponseEntity<String>(JsonUtil.toJson(response), HttpStatus.INTERNAL_SERVER_ERROR);
}} 
pdmoore
  • 66
  • 1
  • 1
  • 5
  • Thanks for the suggestion. But this should get solved by precedence ideally, right? I anyway fixed this by adding the point cut in the same aspect class instead of two different classes – Crane Dec 08 '15 at 17:28
  • Yeah, I think precedence is the "correct" way to fix it. I tossed this out there as a workaround. – pdmoore Dec 08 '15 at 21:47
0

Was able to fix this by adding the pointcut in the same aspect class instead of different aspect class.

Crane
  • 121
  • 2
  • 9