What does server.error.include-binding-errors=on-param in Spring do?
Asked Answered
B

1

16

What does the following setting in application.properties in a Spring application do?

server.error.include-binding-errors=on-param

I can't find it in the documentation.

The always and never values are pretty self-explanatory, but I don't understand on-param.

Benjie answered 10/6, 2021 at 13:44 Comment(0)
R
21

To begin, what I did is to do a global search on server.error.include-binding-errors in the library, which lead me to spring-configuration-metadata.json

    {
      "name": "server.error.include-binding-errors",
      "type": "org.springframework.boot.autoconfigure.web.ErrorProperties$IncludeAttribute",
      "description": "When to include \"errors\" attribute.",
      "sourceType": "org.springframework.boot.autoconfigure.web.ErrorProperties",
      "defaultValue": "never"
    },

We see the related attribute is errors here, and the value class is IncludeAttribute. By checking the documentation in IncludeAttribute#ON_PARAM

public static final ErrorProperties.IncludeAttribute ON_PARAM
Add error attribute when the appropriate request parameter is not "false".

We know that the errors attribute will be added when there is a request parameter that is not "false".


If you want something concrete, let's consider the following example:

Controller

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RestController
public class TestController {
    @PostMapping("/dummy")
    public String test(@Valid @RequestBody DummyDTO dummyDTO) {
        return "";
    }
}

DTO

import javax.validation.constraints.NotNull;

public class DummyDTO {
    @NotNull(message = "mandatoryText can not be null")
    private String mandatoryText;

    private String canBeNullText;

    public String getMandatoryText() {
        return mandatoryText;
    }

    public void setMandatoryText(String mandatoryText) {
        this.mandatoryText = mandatoryText;
    }

    public String getCanBeNullText() {
        return canBeNullText;
    }

    public void setCanBeNullText(String canBeNullText) {
        this.canBeNullText = canBeNullText;
    }
}

Suppose we set
server.error.include-binding-errors=on-param

When we run with parameter errors=false

curl -H "Content-Type: application/json" --data '{"canBeNullText":""}' -X POST http://localhost:8080/dummy?errors=false

the result will not include errors

{
    "timestamp": "2021-06-11T13:38:29.868+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "",
    "path": "/dummy"
} 

When we run with parameter errors=true

curl -H "Content-Type: application/json" --data '{"canBeNullText":""}' -X POST http://localhost:8080/dummy?errors=true

the result will include errors as

{
    "timestamp": "2021-06-11T13:51:00.649+00:00",
    "status": 400,
    "error": "Bad Request",
    "errors": [{
            "codes": ["NotNull.dummyDTO.mandatoryText", "NotNull.mandatoryText", "NotNull.java.lang.String", "NotNull"],
            "arguments": [{
                    "codes": ["dummyDTO.mandatoryText", "mandatoryText"],
                    "arguments": null,
                    "defaultMessage": "mandatoryText",
                    "code": "mandatoryText"
                }
            ],
            "defaultMessage": "mandatoryText can not be null",
            "objectName": "dummyDTO",
            "field": "mandatoryText",
            "rejectedValue": null,
            "bindingFailure": false,
            "code": "NotNull"
        }
    ],
    "path": "/dummy"
}

References:
Implementation for web reactive
DefaultErrorWebExceptionHandler#isIncludeBindingErrors
AbstractErrorWebExceptionHandler#isBindingErrorsEnabled

Implementation for web servlet
BaseErrorController#isIncludeBindingErrors
AbstractErrorController#isBindingErrorsEnabled

Resonate answered 10/6, 2021 at 14:38 Comment(4)
Thanks for the investigation! It's hard for me to interpret what this all implies. Can you explain how ON_PARAM works from a user perspective? For example: Can my application set the "errors" parameter in the ServerRequest? How to do that? Or is the web request which my application receives that includes the "errors" parameter?Benjie
@Lii, thank for your comment, please see if my update makes you clear.Resonate
That is a very thorough investigation, thank you! The edits makes it all very clear indeed. :)Benjie
You have the same behaviour with "server.error.include-message: on_param" and ?message=true. I think it is way better to use it than errors. It will not return all information. Just the message you want. For instance, for 404 error, you can use throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No resource"); If the endpoint does not exist, spring return "message: "No message available". So you can easilly distinguish the 2 cases.Ml

© 2022 - 2024 — McMap. All rights reserved.