Springboot is not throwing the error to the client

Viewed 237

I want that when an error is encountered, the user receives in the exception response to his http call. The error is indeed caught, displayed in the spring logs, but it is not returned to the user. Why ?

My method :

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
      FilterChain chain) {
    try {
      // Check for authorization header existence.
      String header = request.getHeader(JwtConstant.AUTHORIZATION_HEADER_STRING);
      if (header == null || !header.startsWith(JwtConstant.TOKEN_BEARER_PREFIX)) {
        chain.doFilter(request, response);
        return;
      }
      // Validate request..
      UsernamePasswordAuthenticationToken authorization = authorizeRequest(request);
      SecurityContextHolder.getContext().setAuthentication(authorization);
      chain.doFilter(request, response);
    } catch (Exception e) {
      SecurityContextHolder.clearContext();
      throw new InternalServerErrorException("Erreur sur le filtre interne -> " + e.toString());  // Should return this to the user
    }
  }

The error in logs :

.common.application.exception.InternalServerErrorException: Erreur sur le filtre interne -> 
.common.application.exception.InternalServerErrorException: Erreur lors du authorizeRequest

The error Handler :

@ControllerAdvice
public class ApiResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    String typeDateFormat = "yyyy-MM-dd HH:mm:ss";
...

    @ExceptionHandler(InternalServerErrorException.class)
    public final ResponseEntity<ExceptionResponse> handleInternalServerErrorException(InternalServerErrorException ex,
            WebRequest request) {

        ExceptionResponse exceptionResponse = new ExceptionResponse(
                new SimpleDateFormat(typeDateFormat).format(new Date()), ex.getMessage(),
                request.getDescription(false), "500");
        return new ResponseEntity<>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

InternalServerErrorException.java

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class InternalServerErrorException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public InternalServerErrorException(String exception) {
        super(exception);
    }

}

ExceptionResponse.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExceptionResponse {
    
  private String date;
  private String message;
  private String uri;
  private String status;
  
}

The user receive a 403.. i don't know why, but should receive the error that i throw, without any body..

The InternalServerException works outside of the try/catch..

1 Answers

Basically @ControllerAdvice will only work if the exception is thrown from the @Controller / @RestContoller method.

Technically , the spring-mvc framework stuff (i.e @ControllerAdvice) will only take effect for an HTTP request if it can be successfully passed through all the Filter in the SecurityFilterChain (configured by spring-security) and processed by the DispatcherServlet. But now it seems that your exception is thrown from one of the Filter in the SecurityFilterChain before the request reach to DispatcherServlet , and hence @ControllerAdvice will not be invoked to handle this exception.

You have to consult about if there are related configuration in that spring-security filter that allow you to customize the exception. If not , you can still manually do it in that filter since you can access HttpServletResponse from there.

Related