简体   繁体   English

Azure Function v2 在处理 StorageException 后始终返回内部服务器错误 500

[英]Azure Function v2 always returning Internal Server Error 500 after a handled StorageException

Imagine you have an Azure Function (v2) that uses Table storage, you run but the entity with SomePartitionKey/SomeRowKey exists (eg you run the below twice):假设您有一个使用表存储的 Azure 函数 (v2),您运行但具有 SomePartitionKey/SomeRowKey 的实体存在(例如,您运行以下两次):

[FunctionName("SomeEntity")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "someentity")] HttpRequest req,
                                            [Table("SomeEntities")] IAsyncCollector<SomeEntity> collector,
                                            ILogger logger)
{

    try
    {
        SomeEntity se = new SomeEntity()
        {
                PartitionKey = "SomePartitionKey",
                RowKey = "SomeRowKey"
        };
        await collector.AddAsync(se);
        await collector.FlushAsync();

        return new OkResult();
    }
    catch (Microsoft.WindowsAzure.Storage.StorageException e)
    {
        logger.LogError("There was an error processing the request.", e);
        return new StatusCodeResult(409);
    }
}

When this runs and the Entity already exists, as expected, it throws a StorageException.当它运行并且实体已经存在时,正如预期的那样,它会抛出一个 StorageException。 My issue is that even though I catch the exception and attempt to return a StatusCodeResult(409) the actual response sent to the client is always an Internal Server Error (500).我的问题是,即使我捕获异常并尝试返回StatusCodeResult(409) ,发送到客户端的实际响应始终是内部服务器错误 (500)。

My questions are:我的问题是:
a) Is this the result of cleanup logic of the Function attempting to call FlushAsync() again on the collector resulting in an unhandled StorageException which causes an Internal Server Error (500). a) 这是由于函数的清理逻辑试图在收集器上再次调用FlushAsync()导致未处理的 StorageException 导致内部服务器错误 (500) 的结果。 b) If yes to a), is it possible to prevent this? b) 如果 a) 是肯定的,是否可以防止这种情况发生?
c) Aside from checking if the entity exists first is there any best practice for this scenario? c) 除了首先检查实体是否存在之外,是否有针对这种情况的最佳实践?

One of the great things about Azure Functions NuGet packages is that they enable source linking. Azure Functions NuGet 包的一大优点是它们支持源链接。 Ensure you have Enable Source Link support checked in your Visual Studio options, and you'll be able to see exactly what their code is doing.确保您在 Visual Studio 选项中选中了Enable Source Link support ,您将能够准确地看到他们的代码在做什么。 Once your function app is running, you can choose to break when any CLR Exceptions are thrown.函数应用运行后,您可以选择在抛出任何 CLR 异常时中断。

If you do this, you'll see that the exception is thrown as expected from FlushAsync , your code is catching it, and returning the 409 result.如果您这样做,您将看到FlushAsync按预期抛出异常,您的代码正在捕获它,并返回 409 结果。 Then, after your function returns, the same exception is thrown again (because FlushAsync is called again, outside your function), it's caught and a wrapper exception is thrown with the message Error while handling parameter collector after function returned , which in turn is caught and a wrapper exception is thrown with the message Exception while executing function: SomeEntity , which in turn is caught and just a plain old 500 error is returned to the client.然后,在您的函数返回后,再次抛出相同的异常(因为FlushAsync再次被调用,在您的函数之外),它被捕获并抛出一个包装器异常,并在Error while handling parameter collector after function returned抛出Error while handling parameter collector after function returned消息,而后者又被捕获并且Exception while executing function: SomeEntity抛出一个带有消息Exception while executing function: SomeEntity的包装器异常Exception while executing function: SomeEntity ,它反过来被捕获并且只向客户端返回一个普通的旧 500 错误。

So:所以:

a) Is this the result of cleanup logic of the Function attempting to call FlushAsync() again on the collector resulting in an unhandled StorageException which causes an Internal Server Error (500). a) 这是由于函数的清理逻辑试图在收集器上再次调用 FlushAsync() 导致未处理的 StorageException 导致内部服务器错误 (500) 的结果。

Yes.是的。 If you enable Source Link support and Break when Thrown, then you can debug right through the Azure Functions runtime and see this happen.如果启用 Source Link 支持和 Break when Thrown,则可以直接通过 Azure Functions 运行时进行调试并看到这种情况发生。

b) If yes to a), is it possible to prevent this? b) 如果 a) 是肯定的,是否可以防止这种情况发生?

c) Aside from checking if the entity exists first is there any best practice for this scenario? c) 除了首先检查实体是否存在之外,是否有针对这种情况的最佳实践?

I would not recommend check-then-insert.建议先检查再插入。 You'll end up with race conditions.你最终会遇到竞争条件。

From the docs :文档

This output binding does not support updating existing entities.此输出绑定不支持更新现有实体。 Use the TableOperation.Replace operation from the Azure Storage SDK to update an existing entity.使用 Azure 存储 SDK 中的TableOperation.Replace操作更新现有实体。

As a general rule, the Azure Functions binding for any given service is for the simple use case.作为一般规则,任何给定服务的 Azure Functions 绑定都适用于简单用例。 In the case of Azure Storage Tables, the simple use case is only inserting entities.对于 Azure 存储表,简单的用例只是插入实体。

However, you can always just use the Storage SDK yourself.但是,您始终可以自己使用 Storage SDK。 That's pretty much just what the binding is doing for you anyway.无论如何,这几乎就是绑定为您所做的。 This binding does some batching, too, but that's not too hard to implement if you need it.这个绑定也做一些批处理,但如果你需要它并不难实现。

You can also do a "halfway": have the Tables binding bind to a CloudTable instead of an IAsyncCollector<SomeEntity> .您也可以“中途”:将 Tables 绑定绑定到CloudTable而不是IAsyncCollector<SomeEntity> That way you'll automatically use the appropriate connection string;这样,您将自动使用适当的连接字符串; you'll just need to write your own TableOperation.InsertOrReplace code.您只需要编写自己的TableOperation.InsertOrReplace代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Azure Function 来自 SocketException 的代理内部服务器错误 500 - Azure Function Proxy Internal Server Error 500 from SocketException azure api azure 内部服务器错误 500 - azure api azure internal server error 500 RemoteServerException 总是抛出 500 内部服务器错误? - RemoteServerException always throws 500 Internal Server Error? Ajax调用返回500内部服务器错误 - Ajax call returning 500 internal server error 500-在服务器上发布后出现内部服务器错误 - 500 - Internal server error after publish on server 为什么我的 Azure API 在本地环境中运行时返回 500 内部服务器错误? - Why is My Azure API returning 500 internal server error when it works in a local environment? 为什么发布 Azure Function 后出现内部服务器错误? - Why I get Internal Server Error after publishing Azure Function? 预编译的Azure函数输出到Blob存储,收到500个内部服务器错误 - Precompiled Azure Function Output to Blob Storage receiving 500 Internal Server Error .Net Core API 返回 500 Internal Server Error - .Net Core API returning 500 Internal Server Error Auth0 管理 API CreateAsync 返回内部服务器错误 (500) - Auth0 management API CreateAsync returning internal server error (500)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM