I'm writing a simple Kotlin Spring Boot Webflux application. I now want to add some Exception handling which isn't showing the message no matter what I try out.
When I run the application in debug mode in Intellij, I can see it actually gets to my @ControllerAdvice class and correctly populates my custom message object, but it just won't display it as the response message.
My Controller code is:
@RestController
@RequestMapping("/api")
class AppUserController(private val appUserService: AppUserService) {
@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED)
fun addUser(@Valid @RequestBody appUserRequest: AppUserRequest): Mono<AppUserRequest> =
appUserService.addUser(appUserRequest)
}
My service code is:
@Service
class AppUserServiceImpl(private val appUserRepository: AppUserRepository): AppUserService {
override fun addUser(appUserRequest: AppUserRequest): Mono<AppUserRequest> {
val appUser: AppUser = toEntity(appUserRequest)
val userEmail: String = appUser.email
return appUserRepository.findByEmail(userEmail)
.flatMap<AppUserRequest> { Mono.error(BadRequestException("User with email $userEmail already exists.")) }
.switchIfEmpty(appUserRepository.save(appUser)
.map { savedAppUser -> toApi(savedAppUser) }
.log("New app user has been added"))
}
}
And my controller advice code is:
@ControllerAdvice
class ExceptionControllerAdvice {
@ExceptionHandler(BadRequestException::class)
fun handleBadRequestException(exception: BadRequestException): ResponseEntity<AppError> {
val errorMessage = AppError(HttpStatus.BAD_REQUEST.value(),
HttpStatus.BAD_REQUEST.reasonPhrase,
Instant.now(),
exception.localizedMessage)
return ResponseEntity(errorMessage, HttpStatus.BAD_REQUEST)
}
}
What I see as response from Insomnia is:
Please, any assistance would be greatly appreciated! I suspect it's something simple I'm missing.
Update: Immediately I remove my custom error message data class for a String, it actually displays the expected String message. My custom error data class is:
data class AppError(private var errorCode: Int?,
private var status: String?,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'hh:mm:ssZ", timezone = "Europe/London")
private val timestamp: Instant,
private var message: String?)
Maybe the issue is hiding there somewhere.