diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b434be70c..be77daa67d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed `cref` tags not closed in doc comments in CSharp generation. - Deduplicates 4XX and 5XX error mappings when they map to the same type to reduce emitted code. [#4025](https://github.com/microsoft/kiota/issues/4025) - 📢📢📢 Java generation is now stable! 🚀🚀🚀 special thanks to @andreaTP (Red Hat) for all the help. +- Fixed bug where stream responses would generate incorrect partial paging code. [#4207](https://github.com/microsoft/kiota/issues/4207) ## [1.11.1] - 2024-02-05 diff --git a/src/Kiota.Builder/Writers/CLI/CliCodeMethodWriter.cs b/src/Kiota.Builder/Writers/CLI/CliCodeMethodWriter.cs index eac0cb25b8..9d7c94edca 100644 --- a/src/Kiota.Builder/Writers/CLI/CliCodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/CLI/CliCodeMethodWriter.cs @@ -317,7 +317,7 @@ private void AddCustomCommandOptions(LanguageWriter writer, ref List ava parameters.Add((OutputFilterQueryParamType, OutputFilterQueryParamName, null)); availableOptions.Add($"{InvocationContextParamName}.ParseResult.GetValueForOption({outputFilterQueryOptionName})"); - // Add --all option + // Add --all option for pageable data if (isPageable) { var allOptionName = $"{AllParamName}Option"; @@ -632,7 +632,7 @@ protected virtual void WriteCommandHandlerBody(CodeMethod codeElement, CodeClass if (parentClass .UnorderedMethods .FirstOrDefault(x => x.IsOfKind(CodeMethodKind.RequestGenerator) && x.HttpMethod == codeElement.HttpMethod) is not CodeMethod generatorMethod) return; - bool isStream = false; + bool isStreamReq = false; if (requestParams.requestBody is CodeParameter requestBodyParam) { var requestBodyParamType = requestBodyParam.Type as CodeType; @@ -663,7 +663,7 @@ protected virtual void WriteCommandHandlerBody(CodeMethod codeElement, CodeClass } else if (conventions.StreamTypeName.Equals(requestBodyParamType?.Name, StringComparison.OrdinalIgnoreCase)) { - isStream = true; + isStreamReq = true; var pName = requestBodyParam.Name; requestBodyParam.Name = "stream"; // Check for file existence @@ -680,7 +680,7 @@ protected virtual void WriteCommandHandlerBody(CodeMethod codeElement, CodeClass .Select(static x => x?.Name).Where(static x => x != null)); var separator = string.IsNullOrWhiteSpace(parametersList) ? "" : ", "; - WriteRequestInformation(writer, generatorMethod, parametersList, separator, isStream); + WriteRequestInformation(writer, generatorMethod, parametersList, separator, isStreamReq); var errorMappingVarName = "default"; if (codeElement.ErrorMappings.Any()) @@ -695,24 +695,24 @@ protected virtual void WriteCommandHandlerBody(CodeMethod codeElement, CodeClass writer.CloseBlock("};"); } - var requestMethod = "SendPrimitiveAsync"; - var pageInfo = codeElement?.PagingInformation; - if (isVoid || pageInfo != null) + var isStreamResp = conventions.StreamTypeName.Equals(returnType, StringComparison.OrdinalIgnoreCase); + const string SendNoContent = "SendNoContentAsync"; + const string SendStream = "SendPrimitiveAsync"; + if (isVoid) { - requestMethod = "SendNoContentAsync"; + writer.WriteLine($"await {RequestAdapterParamName}.{SendNoContent}(requestInfo, errorMapping: {errorMappingVarName}, cancellationToken: {CancellationTokenParamName});"); } - - if (pageInfo != null) + else if (!isStreamResp && !conventions.IsPrimitiveType(returnType) && codeElement.PagingInformation is { } pi) { - writer.WriteLine($"var pagingData = new PageLinkData(requestInfo, null, itemName: \"{pageInfo.ItemName}\", nextLinkName: \"{pageInfo.NextLinkName}\");"); - writer.WriteLine($"{(isVoid ? string.Empty : "var pageResponse = ")}await {PagingServiceParamName}.GetPagedDataAsync((info, token) => {RequestAdapterParamName}.{requestMethod}(info, cancellationToken: token), pagingData, {AllParamName}, {CancellationTokenParamName});"); + writer.WriteLine($"var pagingData = new PageLinkData(requestInfo, null, itemName: \"{pi.ItemName}\", nextLinkName: \"{pi.NextLinkName}\");"); + writer.WriteLine($"var pageResponse = await {PagingServiceParamName}.GetPagedDataAsync((info, token) => {RequestAdapterParamName}.{SendNoContent}(info, cancellationToken: token), pagingData, {AllParamName}, {CancellationTokenParamName});"); writer.WriteLine("var response = pageResponse?.Response;"); } else { - string suffix = string.Empty; - if (!isVoid) suffix = " ?? Stream.Null"; - writer.WriteLine($"{(isVoid ? string.Empty : "var response = ")}await {RequestAdapterParamName}.{requestMethod}(requestInfo, errorMapping: {errorMappingVarName}, cancellationToken: {CancellationTokenParamName}){suffix};"); + // TODO: Warn when paging information is available on a stream response + // https://github.com/microsoft/kiota/issues/4208 + writer.WriteLine($"var response = await {RequestAdapterParamName}.{SendStream}(requestInfo, errorMapping: {errorMappingVarName}, cancellationToken: {CancellationTokenParamName}) ?? Stream.Null;"); } }