Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConversionErrorHandler not being used after upgrading to 4.4.2 #10808

Open
GeitV opened this issue May 8, 2024 · 0 comments
Open

ConversionErrorHandler not being used after upgrading to 4.4.2 #10808

GeitV opened this issue May 8, 2024 · 0 comments
Labels
priority: high High priority type: bug Something isn't working type: regression A breaking change was introduced in a minor or patch release
Milestone

Comments

@GeitV
Copy link

GeitV commented May 8, 2024

Expected Behavior

We got custom ExceptionHandler that replaced ConversionErrorHandler which worked just fine on 4.3.5. The codebase is Kotlin and this catched errors where data model field was not nullable, but given input was null (so the error response would match what the @validated gives)

Actual Behaviour

After upgrade to 4.4.2, we are getting INTERNAL_SERVER_ERROR instead. Seems like when before the ConversionErrorHandler was used, then it's not any more on nullpointer exceptions.

{
  "direction": "Outgoing",
  "response": "500 Internal Server Error",
  "duration": "271 ms",
  "body": {
    "type": "about:blank",
    "status": 500,
    "detail": "Internal Server Error: Parameter specified as non-null is null: method xx.xx.xxx.model.ModelDto.<init>, parameter firstName",
    "parameters": {}
  }
}

Steps To Reproduce

  1. Add custom request ExceptionHandler:
@Singleton
@Produces
@Replaces(ConversionErrorHandler::class)
class JsonExceptionHandler(
    private val problemErrorResponseProcessor: ProblemErrorResponseProcessor
) : ExceptionHandler<ConversionErrorException, HttpResponse<*>> {

    override fun handle(request: HttpRequest<*>, exception: ConversionErrorException): HttpResponse<*> {
        val exceptionMessage = exception.toString()

        if (exceptionMessage.contains("No enum constant")) {
            return processEnumError(request, exception.conversionError.cause.toString())
        }
        if (exceptionMessage.contains("Parameter specified as non-null is null") ||
            exceptionMessage.contains(Regex("for value \\[(NaN|undefined|null)] due to"))
        ) {
            return processNullFieldError(request, exception.conversionError.cause.toString())
        }

        log.error(exception) { "Got exception from parsing request" }
        return HttpResponse.serverError(exception)
    }

    private fun processNullFieldError(request: HttpRequest<*>, cause: String): HttpResponse<*> {
        val field = getFieldPath(cause)
        val e = ValidationUtil.createValidationError(field, "Must not be null")
        val response = HttpResponse.status<Problem>(HttpStatus.BAD_REQUEST)

        return problemErrorResponseProcessor.processResponse(
            ErrorContext.builder(request).cause(e).errorMessage(e.message).build(),
            response
        )
    }

    private fun processEnumError(request: HttpRequest<*>, cause: String): HttpResponse<*> {
        val field = getFieldPath(cause)
        val value = enumRegex.find(cause)?.value

        val e = ValidationUtil.createValidationError(field, "Unknown enum value '$value'", value)
        val response = HttpResponse.status<Problem>(HttpStatus.BAD_REQUEST)

        return problemErrorResponseProcessor.processResponse(
            ErrorContext.builder(request).cause(e).errorMessage(e.message).build(),
            response
        )
    }

    companion object {
        private val log = KotlinLogging.logger {}

        private val fieldRegex = Regex("\\[(?!class)[^]]*\\s([^]]*)]")
        private val enumRegex = Regex("[^.]*\$")

        fun getFieldPath(errorMessage: String): String {
            val matches = fieldRegex.findAll(errorMessage)

            return matches.map { it.groupValues[1] }.joinToString(".")
        }
    }
}
  1. Send POST request to endpoint, that has non-null field OR send POST request to endpoint with unknown enum

Environment Information

  • Kotlin 1.9.23

Example Application

No response

Version

4.4.2

@GeitV GeitV changed the title ConversionErrorHandler not being used after upgrading to 4.4.x ConversionErrorHandler not being used after upgrading to 4.4.2 May 8, 2024
@graemerocher graemerocher added type: bug Something isn't working type: regression A breaking change was introduced in a minor or patch release priority: high High priority labels May 8, 2024
@graemerocher graemerocher modified the milestones: 4.5.0, 4.4.9 May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: high High priority type: bug Something isn't working type: regression A breaking change was introduced in a minor or patch release
Projects
Status: No status
Development

No branches or pull requests

2 participants