0

I have a Spring Boot application and I just added Sentry to report and track errors. The problem I'm having is that there are certain exceptions that I handle in my application that are not erroneous conditions. For example, I an action with a @Valid annotated parameter:

@RestController
@RequestMapping("/v1/current-account")
public class CurrentAccountController extends Controller {
    @PutMapping
    public ResponseEntity<?> updateAccount(@RequestBody @Valid Account account, Authentication auth) {
    ...

When the account is invalid, it raises MethodArgumentNotValidException. Because of other cases similar to that, I have an exception handler that looks like this:

@ControllerAdvice
public class RestExceptionHandler {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleValidationError(MethodArgumentNotValidException ex, HttpServletRequest request) {
        // ...
    }

    @ExceptionHandler(NotFoundException.class)
    public ResponseEntity<?> handleNotFoundException(NotFoundException ex, HttpServletRequest request) {
        // ...
    }

    @ExceptionHandler(BadRequestException.class)
    public ResponseEntity<?> handleValidationError(BadRequestException ex, HttpServletRequest request) {
        // ...
    }
}

which essentially turns some exceptions into responses that are not errors.

When I added Sentry, following the documentation:

@Configuration
public class FactoryBeanAppConfig {
    @Bean
    public HandlerExceptionResolver sentryExceptionResolver() {
        return new SentryExceptionResolver();
    }

    @Bean
    public ServletContextInitializer sentryServletContextInitializer() {
        return new SentryServletContextInitializer();
    }
}

my custom exception handlers are no longer used. Instead, the exception gets reported to Sentry.

How do I make my exception handlers happen before Sentry?

Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622
  • I think you just have to specifiy the order of the different HandlerExceptionResolvers. Maybe having a look at this answer will help: https://stackoverflow.com/a/19500823/2576531 – Yannic Bürgmann Jan 23 '18 at 13:00

3 Answers3

1

You could subclass SentryExceptionResolver to change the order number to be 1 higher than the order of your custom handler, right now it is set to MIN_VALUE: https://github.com/getsentry/sentry-java/blob/c856b762047fe00115000a8d76b027e5157be950/sentry-spring/src/main/java/io/sentry/spring/SentryExceptionResolver.java#L30-L34

Alternatively, you could try using a Sentry logging integration (log4j or logback) instead of the Spring integration. This will allow you to report anything that goes to a logger at level ERROR (for example). It's really up to you whether this is a simpler/better integration than going through Spring itself.

Brett
  • 798
  • 1
  • 4
  • 11
1

With the latest version, you can change the priority of the resolver. Just make sure that your own exception handler has a higher priority than the one you set for sentry's resolver. For instance:

sentry:
    exception-resolver-order: 2

And in your class:

import org.springframework.core.annotation.Order;

@RestControllerAdvice
@Order(1)
public class CustomExceptionHandler {
  // ...
}
Vianney Dupoy de Guitard
  • 2,254
  • 1
  • 14
  • 10
0

I added these two annotations to RestExceptionHandler:

import org.springframework.core.annotation.Order;
import javax.annotation.Priority;

@Priority(1)
@Order(1)

The reason why I added both is because apparently the order is non-deterministic and I stopped being able to reproduce the problem. Since I added these two annotations it hasn't happen again but due to the non-deterministic nature, I don't know if I solved the problem or not.

If it reappears, I'll come back and update this answer. I would also like to know which of the two annotations is having the desired effect, but I can't properly test it right now.

Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622