micronaut-core icon indicating copy to clipboard operation
micronaut-core copied to clipboard

Add config option for strict request argument error checking

Open yawkat opened this issue 3 years ago • 12 comments

When the value of a request argument (e.g. a @QueryValue) is invalid, but the parameter is marked @Nullable, strict conversion checking will produce an error. Without this option enabled, the parameter will simply be set to null.

I've added a parameter to the RequestArgumentSatisfier constructor. The class is @Internal and a code search of the micronaut-projects org shows no subclasses outside micronaut-core, so this seems safe.

Fixes #5135

yawkat avatar Feb 01 '22 10:02 yawkat

Should we also be failing for Optionals?

Adding a test of

        HttpMethod.GET  | '/parameterNullable/optional-named?maximum=inv'         | null      | HttpStatus.BAD_REQUEST

and a Get handler of

        @Get("/optional-named")
        String optionalNamed(@QueryValue('maximum') Optional<Integer> max) {
            "Parameter Value: $max"
        }

Fails as max is set to Optional.empty(), and the request succeeds

timyates avatar Feb 01 '22 11:02 timyates

Also, given:

        HttpMethod.GET  | '/parameterNullable/named-list?max=inv&max=2'           | null                  | HttpStatus.BAD_REQUEST

With a handler of:

        @Get("/named-list")
        String namedList(@QueryValue('max') @Nullable List<Integer> maxList) {
            "Parameter Value: $maxList"
        }

We get an OK response with a result of Parameter Value: [2]

~~I think we need to make this change https://github.com/micronaut-projects/micronaut-core/pull/6808/files#diff-fb96e6a08d20e10f1121573768dd86c523b72869333bf2278a20278a155b9c16 so the collection errors get passed up~~

EDIT: Nope...that's not enough 🤔 posted the fix (I think) in the review comment

timyates avatar Feb 01 '22 11:02 timyates

Optional should be easy, it's just the code path above the ones that already changed. Will discuss in the meeting

yawkat avatar Feb 01 '22 13:02 yawkat

also decided to test making this a ApplicationContextBuilder-level setting instead, will test.

yawkat avatar Feb 01 '22 15:02 yawkat

This should go into 3.3.x IMO as although this is a new configuration option, the existing behaviour is broken and inconsistent. I understand the motivation to not break existing applications but it makes no sense that the following:

@Get("/{num}")
String get(@Nullable Long num) {
    //
}

With a request of /junk results in an exception, whilst the following:

@Get("/{?num}")
String get(@QueryValue @Nullable Long num) {

}

With a request of /?num=junk does not and ignores the error silently.

graemerocher avatar Feb 01 '22 15:02 graemerocher

@jameskleeh one problem with doing this as a more general setting is that we have to decide now where to implement this strict conversion checking. We can't add the stricter checks to other places later, without breaking compatibility.

yawkat avatar Feb 02 '22 10:02 yawkat

any idea when this might get merged?

kevin-wise avatar Dec 21 '22 22:12 kevin-wise

@yawkat can you rebase this and maybe we should make this the default for 4.x?

graemerocher avatar Jan 02 '23 09:01 graemerocher

Yea I made this PR draft because I wanted to try to change it at a higher level (in ConversionService) but I dont think thats viable, so this PR should be fine once rebased.

yawkat avatar Jan 02 '23 09:01 yawkat

@yawkat should we close this?

sdelamo avatar Jan 09 '24 10:01 sdelamo

no it's still on my todo. just not this approach

yawkat avatar Jan 09 '24 11:01 yawkat

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Feb 07 '24 21:02 CLAassistant