diff --git a/dotnet/src/IntegrationTests/Plugins/OpenApi/RepairServiceTests.cs b/dotnet/src/IntegrationTests/Plugins/OpenApi/RepairServiceTests.cs index 98e282175bf5..53e5f5f48828 100644 --- a/dotnet/src/IntegrationTests/Plugins/OpenApi/RepairServiceTests.cs +++ b/dotnet/src/IntegrationTests/Plugins/OpenApi/RepairServiceTests.cs @@ -201,6 +201,8 @@ public async Task KernelFunctionCanceledExceptionIncludeRequestInfoAsync() catch (KernelFunctionCanceledException ex) { Assert.Equal("The invocation of function 'updateRepair' was canceled.", ex.Message); + Assert.Equal("Patch", ex.Data["http.request.method"]); + Assert.Equal("https://piercerepairsapi.azurewebsites.net/repairs", ex.Data["url.full"]); Assert.NotNull(ex.InnerException); Assert.Equal("Patch", ex.InnerException.Data["http.request.method"]); Assert.Equal("https://piercerepairsapi.azurewebsites.net/repairs", ex.InnerException.Data["url.full"]); diff --git a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs index 9e50f653f5f8..11ad6e109084 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Functions/KernelFunction.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System; +using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; @@ -432,7 +433,12 @@ private static void HandleException( // visible to a consumer if that's needed. if (ex is OperationCanceledException cancelEx) { - throw new KernelFunctionCanceledException(kernel, kernelFunction, arguments, result, cancelEx); + KernelFunctionCanceledException kernelEx = new(kernel, kernelFunction, arguments, result, cancelEx); + foreach (DictionaryEntry entry in cancelEx.Data) + { + kernelEx.Data.Add(entry.Key, entry.Value); + } + throw kernelEx; } } } diff --git a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs index c1d2cf7b64cc..b0278778354e 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Functions/KernelFunctionFromMethodTests1.cs @@ -814,13 +814,13 @@ async Task AssertParameterType(T expected) { var d = (T actual) => { - //Check the argument is of the expected type + //Check the argument is of the operationCancelled type if (actual is not null) { Assert.IsType(actual); } - //Check the argument value is the expected value + //Check the argument value is the operationCancelled value Assert.Equal(expected, actual); }; @@ -1375,6 +1375,25 @@ public async Task ItCanDeserializeThirdPartyJsonPrimitivesAsync() Assert.Equal(28, actualArgValue.Id); } + [Fact] + public async Task ItThrowsKernelFunctionCanceledExceptionWhenOperationIsCanceledAsync() + { + // Arrange + var arguments = new KernelArguments(); + var operationCancelled = new OperationCanceledException("OperationCanceledException"); + operationCancelled.Data.Add("Key", "Value"); + KernelFunction func = KernelFunctionFactory.CreateFromMethod(() => { throw operationCancelled; }); + + // Act + Exception actual = await Record.ExceptionAsync(() => func.InvokeAsync(this._kernel, arguments)); + + // Assert + Assert.NotNull(actual); + Assert.True(actual is KernelFunctionCanceledException); + Assert.True(actual.Data.Contains("Key")); + Assert.Equal("Value", actual.Data["Key"]); + } + #pragma warning disable CA1812 // Avoid uninstantiated internal classes private sealed class CustomTypeForJsonTests #pragma warning restore CA1812 // Avoid uninstantiated internal classes