@ControllerAdviceclass GlobalExceptionHandler {    
@ExceptionHandler(
        ServerWebInputException::class,
        HttpMessageNotReadableException::class
    )    
@ResponseBody    fun handleHttpMessageNotReadableException(e: Exception): ResponseEntity<ErrorDTO> {
        logError("Bad Request", e)
        val message = when (val cause = e.cause?.findCause()) {
            is InvalidFormatException -> "Can't read value '${cause.value}' for field '${cause.path.errorPath()}'"
            is MissingKotlinParameterException -> "Missing required field '${cause.path.errorPath()}'"
            is ServerWebInputException -> cause.reason
            else -> cause?.message ?: e.message
        }
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorDTO(REQUIRED_PARAMETER_ABSENT, message))
    }    
@ExceptionHandler(
        WebExchangeBindException::class
    )    
@ResponseBody    fun handleMethodArgumentNotValidException(e: WebExchangeBindException): ResponseEntity<ErrorDTO> {
        logError("Bad Request", e)
        val message = e.bindingResult.allErrors.joinToString(prefix = "Validation failure. ") {
            when (it) {
                is FieldError -> "Field '${it.field}': ${it.defaultMessage}"
                else -> it.defaultMessage.orEmpty()
            }
        }
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorDTO(REQUIRED_PARAMETER_ABSENT, message))
    }    
@ExceptionHandler(
        Error::class,
        Exception::class
    )    
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)    
@ResponseBody    fun internalServerError(e: Exception): ResponseEntity<ErrorDTO> {
        logError("Internal server error", e)
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(ErrorDTO(INTERNAL_SERVER_ERROR_CODE, e.message))
    }
    companion object : Loggable
}
private const val INTERNAL_SERVER_ERROR_CODE = "INTERNAL_SERVER_ERROR"
private const val REQUIRED_PARAMETER_ABSENT = "REQUIRED_PARAMETER_ABSENT"