Set EnableUserCodeException capability to true by default (#2702)

This commit is contained in:
Lilian Kasem 2024-09-17 15:59:28 -07:00 коммит произвёл Fabio Cavalcante
Родитель 5f237161a2
Коммит 2c06eafccc
4 изменённых файлов: 39 добавлений и 25 удалений

Просмотреть файл

@ -16,21 +16,25 @@
- Capability `IncludeEmptyEntriesInMessagePayload` is now enabled by default (#2701)
- This means that empty entries will be included in the function trigger message payload by default.
- To disable this capability and return to the old behaviour, set `IncludeEmptyEntriesInMessagePayload` to `false` in the worker options.
```csharp
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(builder =>
{
}, options =>
{
options.IncludeEmptyEntriesInMessagePayload = false;
})
.Build();
```
- Capability `EnableUserCodeException` is now enabled by default (#2702)
- This means that exceptions thrown by user code will be surfaced to the Host as their original exception type, instead of being wrapped in an RpcException.
- To disable this capability and return to the old behaviour, set `EnableUserCodeException` to `false` in the worker options.
- The `EnableUserCodeException` property in WorkerOptions has been marked as obsolete and may be removed in a future release.
- Rename `ILoggerExtensions` to `FunctionsLoggerExtensions` to avoid naming conflict issues (#2716)
- Updating `Azure.Core` to 1.41.0
- Updated service registrations for bootstrapping methods to ensure idempotency.
##### Setting worker options example
```csharp
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(options =>
{
options.EnableUserCodeException = false;
options.IncludeEmptyEntriesInMessagePayload = false;
})
```
### Microsoft.Azure.Functions.Worker.Grpc 2.0.0
- Removed fallback command line argument reading code for grpc worker startup options. (#1908)

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Text.Json;
using Azure.Core.Serialization;
@ -32,13 +33,16 @@ namespace Microsoft.Azure.Functions.Worker
// Enable these by default, although they are not strictly required and can be removed
{ WorkerCapabilities.HandlesWorkerTerminateMessage, bool.TrueString },
{ WorkerCapabilities.HandlesInvocationCancelMessage, bool.TrueString },
{ WorkerCapabilities.IncludeEmptyEntriesInMessagePayload, bool.TrueString }
{ WorkerCapabilities.IncludeEmptyEntriesInMessagePayload, bool.TrueString },
{ WorkerCapabilities.EnableUserCodeException, bool.TrueString }
};
/// <summary>
/// Gets or sets the flag for opting in to unwrapping user-code-thrown
/// exceptions when they are surfaced to the Host.
/// Gets or sets a value indicating whether exceptions thrown by user code should be unwrapped
/// and surfaced to the Host as their original exception type, instead of being wrapped in an RpcException.
/// The default value is <see langword="true"/>.
/// </summary>
[Obsolete("This is now the default behavior. This property may be unavailable in future releases.", false)]
public bool EnableUserCodeException
{
get => GetBoolCapability(nameof(EnableUserCodeException));

Просмотреть файл

@ -9,7 +9,6 @@ using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core.Serialization;
using Microsoft.Azure.Functions.Tests;
using Microsoft.Azure.Functions.Worker.Context.Features;
using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata;
@ -178,6 +177,8 @@ namespace Microsoft.Azure.Functions.Worker.Tests
[Theory]
[InlineData("IncludeEmptyEntriesInMessagePayload", true, "IncludeEmptyEntriesInMessagePayload", true, "True")]
[InlineData("IncludeEmptyEntriesInMessagePayload", false, "IncludeEmptyEntriesInMessagePayload", false)]
[InlineData("EnableUserCodeException", true, "EnableUserCodeException", true, "True")]
[InlineData("EnableUserCodeException", false, "EnableUserCodeException", false)]
public void InitRequest_ReturnsExpectedCapabilities_BasedOnWorkerOptions(
string booleanPropertyName,
bool booleanPropertyValue,
@ -233,6 +234,7 @@ namespace Microsoft.Azure.Functions.Worker.Tests
}
Assert.Collection(response.Capabilities.OrderBy(p => p.Key),
c => AssertKeyAndValue(c, "EnableUserCodeException", bool.TrueString),
c => AssertKeyAndValue(c, "HandlesInvocationCancelMessage", bool.TrueString),
c => AssertKeyAndValue(c, "IncludeEmptyEntriesInMessagePayload", bool.TrueString),
c => AssertKeyAndValue(c, "RawHttpBodyBytes", bool.TrueString),

Просмотреть файл

@ -77,14 +77,15 @@ namespace Microsoft.Azure.Functions.Worker.Tests
{
_mockApplication
.Setup(m => m.InvokeFunctionAsync(It.IsAny<FunctionContext>()))
.Throws(new AggregateException(new Exception[] { new TaskCanceledException() }));
.Throws(new AggregateException(new TaskCanceledException()));
var request = TestUtility.CreateInvocationRequest("abc");
var invocationHandler = CreateInvocationHandler();
var response = await invocationHandler.InvokeAsync(request);
Assert.Equal(StatusResult.Types.Status.Cancelled, response.Result.Status);
Assert.Contains("TaskCanceledException", response.Result.Exception.Message);
Assert.Equal("System.AggregateException", response.Result.Exception.Type);
Assert.Contains("A task was canceled", response.Result.Exception.Message);
}
[Fact]
@ -129,15 +130,16 @@ namespace Microsoft.Azure.Functions.Worker.Tests
}
/// <summary>
/// Test unwrapping user code exception functionality.
/// Test unwrapping user code exception functionality.
/// EnableUserCodeException capability is true by default.
/// </summary>
[Fact]
public async Task InvokeAsync_UserCodeThrowsException_OptionEnabled()
{
var exceptionMessage = "user code exception";
var mockOptions = new OptionsWrapper<WorkerOptions>(new()
{
EnableUserCodeException = true,
Serializer = new JsonObjectSerializer()
});
@ -156,23 +158,24 @@ namespace Microsoft.Azure.Functions.Worker.Tests
}
/// <summary>
/// Test keeping user code exception wrapped as RpcException.
/// Test keeping user code exception wrapped as RpcException.
/// </summary>
[Fact]
public async Task InvokeAsync_UserCodeThrowsException_OptionDisabled()
{
var exceptionMessage = "user code exception";
var mockOptions = new WorkerOptions()
var mockOptions = new OptionsWrapper<WorkerOptions>(new()
{
Serializer = new JsonObjectSerializer(),
EnableUserCodeException = false
};
});
_mockApplication
.Setup(m => m.InvokeFunctionAsync(It.IsAny<FunctionContext>()))
.Throws(new Exception(exceptionMessage));
var request = TestUtility.CreateInvocationRequest("abc");
var invocationHandler = CreateInvocationHandler();
var invocationHandler = CreateInvocationHandler(workerOptions: mockOptions);
var response = await invocationHandler.InvokeAsync(request);
Assert.Equal(StatusResult.Types.Status.Failure, response.Result.Status);
@ -239,8 +242,9 @@ namespace Microsoft.Azure.Functions.Worker.Tests
var response = await invocationHandler.InvokeAsync(request);
Assert.Equal(StatusResult.Types.Status.Failure, response.Result.Status);
Assert.Contains("InvalidOperationException: whoops", response.Result.Exception.Message);
Assert.Contains("CreateContext", response.Result.Exception.Message);
Assert.Equal("System.InvalidOperationException", response.Result.Exception.Type);
Assert.Contains("whoops", response.Result.Exception.Message);
Assert.Contains("CreateContext", response.Result.Exception.StackTrace);
}
[Fact]