Skip to content

Expose exception details so I can handle specific errors differently, and customise the error message #1930

Open
@aSemy

Description

@aSemy

What is your use-case and why do you need this feature?

I have a Spring Boot REST API and I want to control what error codes are returned if there's a problem with some JSON.

At the moment I use Jackson, and in a @ControllerAdvice class I can handle the Jackson exceptions. They provide specific data about the JSON mapping failure.

@ControllerAdvice
class ControllerExceptionHandler {

    @ExceptionHandler(JsonProcessingException::class)
    fun handleJsonError(exception: JsonProcessingException): ResponseEntity<Any> {

        val error = when (exception) {
            // ...
            is UnrecognizedPropertyException -> "${cause.propertyName} unrecognised")
            // ...
        }

        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error)
    }

I can't do this with Kotilnx Serialization because the exceptions are internal, and data about the exceptions gets concatenated into a string.

@ExceptionHandler(kotlinx.serialization.SerializationException::class)
fun handleKotlinxSerializationException(exception: SerializationException): ResponseEntity<Any> {
    when (exception) {
        // ERROR Cannot access 'MissingFieldException': it is internal in 'kotlinx.serialization'
        is kotlinx.serialization.MissingFieldException -> ...
    }
}

Describe the solution you'd like

I'd like to do the same with the Kotlinx Serialization exceptions. Here are some suggestions:

  1. make the existing exceptions public, and add fields so I can access the exact problem
    @PublishedApi
    public class MissingFieldException(  // make public
       val fieldNames: List<String>, // expose the specific problem
       val cause: Exception?,
     ) : SerializationException("Field ... was missing...", cause)
  2. Keep the exceptions internal, but provide some public data class and add it to SerializationException
    sealed interface SerializationExceptionDetail {
        data class MissingFields(
            val missingFields: List<String>
        ): SerializationExceptionDetail
        
        data class UnknownField(
            val unknownFields: List<String>
        ): SerializationExceptionDetail
        
        // ...
    }
    And add the detail to the existing public exception
    public open class SerializationException(
      val detail: SerializationExceptionDetail
    ) : IllegalArgumentException {

Related:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions