4

I want to update my application from Spring Boot 2.2.8 to 2.3.1 When I run the application after the update, my globalExceptionHandler won't work anymore correctly. My case was to handle the error, when a invalid JSON-Body is in the request.

Application

package com.schaerer.coffeelink.remote;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.kafka.annotation.EnableKafka;

@Slf4j
@SpringBootApplication
@EnableKafka
public class Application {

  public static void main(final String[] args) { //NOSONAR
    SpringApplication.run(Application.class, args);
    log.info("Started application. Swagger available at http://localhost:8080/swagger-ui.html");
  }
}

Controller

package com.schaerer.coffeelink.remote.boundary.v1;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.schaerer.coffeelink.remote.boundary.v1.dto.*;
import com.schaerer.coffeelink.remote.controller.v1.ActionController;
import com.schaerer.coffeelink.remote.controller.v1.BidiCommandController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@RestController
@Validated
@RequestMapping(value = "v1/remote", produces = MediaType.APPLICATION_JSON_VALUE)
@Tag(name = "remote-bidi-command")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BidiCommandResource {

  private final BidiCommandController bidiCommandController;
  private final ActionController actionController;
  private final ObjectMapper mapper;

  @ExceptionHandler({IllegalArgumentException.class})
  public ResponseEntity<Object> handleException(final IllegalArgumentException illegalArgumentException) {
    return new ResponseEntity<>(illegalArgumentException.getMessage(), HttpStatus.BAD_REQUEST);
  }

  @PostMapping
  @Operation(summary = "apply bidi command 2.0")
  public BidiCommandReturnDto applyBidiCommand(@Parameter(name = "applyBidiCommand")
                                                         @Validated({ActionDto.CreateValidation.class, BidiCommandDto.CreateValidation.class})
                                           @RequestBody final BidiCommandDto bidiCommandDto) {
        return bidiCommandController.applyBidiCommand(bidiCommandDto);
  }
}

ExceptionHandler

package com.schaerer.coffeelink.remote.boundary.v1;

import com.fasterxml.jackson.databind.JsonMappingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

  @ExceptionHandler(value = {JsonMappingException.class})
  public ResponseEntity<Object> handleJacksonError(final JsonMappingException ex, final WebRequest request) {
    log.error("Cannot parse request. {}", request.getDescription(true), ex);
    return handleExceptionInternal(ex, ex.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST, null);
  }
}

I haven't change any code since the update. The response code is as before 400 Bad Request but the response body is empty and my handler isn't called.

Logs:

13:13:53.987 [http-nio-8080-exec-3] TRACE org.hibernate.internal.SessionImpl - Opened Session [6570b352-8067-49d2-bc46-c503917f4c8d] at timestamp: 1595502833972 13:13:53.991 [http-nio-8080-exec-3] TRACE o.s.t.s.TransactionSynchronizationManager - Bound value [org.springframework.orm.jpa.EntityManagerHolder@72dd1712] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@38c55a8a] to thread [http-nio-8080-exec-3] 13:13:54.011 [http-nio-8080-exec-3] DEBUG o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Could not resolve parameter [0] in public com.schaerer.coffeelink.remote.boundary.v1.dto.BidiCommandReturnDto com.schaerer.coffeelink.remote.boundary.v1.BidiCommandResource.applyBidiCommand(com.schaerer.coffeelink.remote.boundary.v1.dto.BidiCommandDto): JSON parse error: Unexpected character ('' (code 92)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('' (code 92)): was expecting double-quote to start field name at [Source: (PushbackInputStream); line: 8, column: 54] (through reference chain: com.schaerer.coffeelink.remote.boundary.v1.dto.BidiCommandDto["parameters"]) 13:13:54.012 [http-nio-8080-exec-3] TRACE o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'globalExceptionHandler' 13:13:54.012 [http-nio-8080-exec-3] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Using @ExceptionHandler com.schaerer.coffeelink.remote.boundary.v1.GlobalExceptionHandler#handleException(Exception, WebRequest) 13:13:54.013 [http-nio-8080-exec-3] TRACE o.s.w.s.m.m.a.ServletInvocableHandlerMethod - Arguments: [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('' (code 92)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('' (code 92)): was expecting double-quote to start field name at [Source: (PushbackInputStream); line: 8, column: 54] (through reference chain: com.schaerer.coffeelink.remote.boundary.v1.dto.BidiCommandDto["parameters"]), ServletWebRequest: uri=/v1/remote/;client=0:0:0:0:0:0:0:1] 13:13:54.015 [http-nio-8080-exec-3] DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - No match for [/], supported: [] 13:13:54.016 [http-nio-8080-exec-3] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('' (code 92)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('' (code 92)): was expecting double-quote to start field name at [Source: (PushbackInputStream); line: 8, column: 54] (through reference chain: com.schaerer.coffeelink.remote.boundary.v1.dto.BidiCommandDto["parameters"])] 13:13:54.016 [http-nio-8080-exec-3] TRACE o.s.web.servlet.DispatcherServlet - No view rendering, null ModelAndView returned.

Any ideas?

5
  • Can you update your question with @SpringBootApplication class and any one of the rest controller? Commented Jul 23, 2020 at 10:36
  • Ok, I see that's this exception is not throwed anymore from spring, so the ExceptionHandler can't work anymore. Any ideas how can handle the error elsewhere? Commented Jul 23, 2020 at 11:05
  • What error is being thrown now? Commented Jul 23, 2020 at 11:06
  • You can try changing the @ExceptionHandler to catch all exceptions and see if Spring is maybe throwing another exception you can use now. Commented Jul 23, 2020 at 11:09
  • unfortunately no exception thrown anymore :( Commented Jul 23, 2020 at 11:19

1 Answer 1

2

I've found a solution when I remove the ResponseEntityExceptionHandler extension. Here my solution:

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

  @ExceptionHandler(value = {HttpMessageNotReadableException.class})
  public ResponseEntity<Object> handleJacksonError(final JsonMappingException ex, final WebRequest request) {
    log.error("Cannot parse request. {}", request.getDescription(true), ex);
    return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.