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

HTTP generates an error 'Failed to convert argument [q] for value [null] ' after migrating to Micronaut 4 #10263

Open
loicmathieu opened this issue Dec 14, 2023 · 1 comment

Comments

@loicmathieu
Copy link

Expected Behavior

The endpoint works in both Micronaut 3 and 4

Actual Behaviour

After migrating to Micronaut 4, one of our HTTP endpoint failed with the following error:

Failed to convert argument [q] for value [null] due to: Cannot construct instance of `io.micronaut.core.convert.value.ConvertibleValues` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information\n at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 1

This is the endpoint in question, it is called in POST with a JSON body.

    @ExecuteOn(TaskExecutors.IO)
    @Post(uri = "executions/daily")
    @Operation(tags = {"Stats"}, summary = "Get daily statistics for executions")
    public List<DailyExecutionStatistics> dailyStatistics(
        @Parameter(description = "A string filter") @Nullable String q,
        @Parameter(description = "A namespace filter prefix") @Nullable String namespace,
        @Parameter(description = "A flow id filter") @Nullable String flowId,
        @Parameter(description = "The start datetime, default to now - 30 days") @Nullable @Format("yyyy-MM-dd'T'HH:mm[:ss][.SSS][XXX]") ZonedDateTime startDate,
        @Parameter(description = "The end datetime, default to now") @Nullable @Format("yyyy-MM-dd'T'HH:mm[:ss][.SSS][XXX]") ZonedDateTime endDate
    ) {
        // ...
    }

We have multiple endpoints and only this one fail, we notice that even if we use a JSON body, the request body is not bind to a single POJO but to multiple request parameters. This may be the cause of the issue.

Steps To Reproduce

It can be shown in action in the following branch and this test shows the issue.

Environment Information

No response

Example Application

No response

Version

4.0.7

@loicmathieu
Copy link
Author

Moving to a POJO for the request body instead of multiple parameters fixes the issue.

    @ExecuteOn(TaskExecutors.IO)
    @Post(uri = "executions/daily")
    @Operation(tags = {"Stats"}, summary = "Get daily statistics for executions")
    public List<DailyExecutionStatistics> dailyStatistics(@Body @Valid StatisticRequest statisticRequest) {
        // @TODO: seems to be converted back to utc by micronaut
        return executionRepository.dailyStatistics(
            statisticRequest.q(),
            tenantService.resolveTenant(),
            statisticRequest.namespace(),
            statisticRequest.flowId(),
            statisticRequest.startDate() != null ? statisticRequest.startDate().withZoneSameInstant(ZoneId.systemDefault()) : null,
            statisticRequest.endDate() != null ? statisticRequest.endDate().withZoneSameInstant(ZoneId.systemDefault()) : null,
            null,
            false
        );
    }

@Introspected
    public record StatisticRequest(
        @Parameter(description = "A string filter") @Nullable String q,
        @Parameter(description = "A namespace filter prefix") @Nullable String namespace,
        @Parameter(description = "A flow id filter") @Nullable String flowId,
        @Parameter(description = "A flow id filter") @Nullable @Format("yyyy-MM-dd'T'HH:mm[:ss][.SSS][XXX]") ZonedDateTime startDate,
        @Parameter(description = "The end datetime, default to now") @Nullable @Format("yyyy-MM-dd'T'HH:mm[:ss][.SSS][XXX]")ZonedDateTime endDate) {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant