【问题标题】:How to catch an Exception throw by Azure Table in an async Azure Function HTTP Triggered function如何在异步 Azure 函数 HTTP 触发函数中捕获 Azure 表引发的异常
【发布时间】:2019-07-17 07:40:14
【问题描述】:

我有一个 Azure 函数 HTTP 触发函数,它写入可能以重复条目结尾的 Azure 表。我注意到,即使我尝试/捕获了整个函数,仍然会有一个异常“泄漏”给函数运行器,从而返回 HTTP 500。有没有办法捕获这种异常?

这是代码的缩小版:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage;

namespace FunctionTest
{
    public class Entry
    {
        public string PartitionKey { get; set; }
        public string RowKey { get; set; }
    }
    public static class Debug
    {
        [FunctionName("Debug")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]
            HttpRequest req,
            [Table("Debug")]
            IAsyncCollector<Entry> tableBinding,
            ILogger log)
        {
            try
            {
                await tableBinding.AddAsync(new Entry()
                {
                    PartitionKey = "1111",
                    RowKey = "1111",
                });
                await tableBinding.FlushAsync();
            }
            catch (StorageException)
            {
                // we expect an Exception "The specified entity already exists"
                return new OkObjectResult("This passes test");
            }

            return new OkObjectResult("This passes test too");
        }
    }
}

代码是在 Azure Function runtime 2.0(.NET Core 版本)下编写的。

触发/api/debug 两次或更多次,您将看到:

  • HTTP 500
  • catch{} 代码已输入,但仍返回 HTTP 500(!)
  • 在 Application Insights 中,每个请求调用两个表依赖项(不应该发生,文档说表没有自动重试)

【问题讨论】:

  • 你没有捕捉到所有的异常类型,所以当然异常可能会泄漏。您是否 100% 确定您没有因为没有通用的 system.exception catch 块而错过异常?
  • 也有可能,但他说,流进入catch块,仍然报500。
  • @Charleh 在我来这里询问之前我已经做过实验,并且捕获 Exception 根本不起作用。提供的代码是重现问题的最小版本,不是我在实际项目中写的。

标签: c# .net-core azure-functions azure-table-storage azure-function-async


【解决方案1】:

您的 try/catch 块应如下所示以捕获所有错误

try
{

}
catch (StorageException)
{
    return new OkObjectResult("This passes test");
}
catch (Exception ex)
{
    // return different error code
}

【讨论】:

  • 提供的代码只是重现问题的最小版本。在我自己的代码中,我尝试了多种方法,包括捕获通用异常,并且我有大量日志记录,所以我很确定 StorageException 是唯一的异常类型。
【解决方案2】:

我猜,使用 IAsyncCollector&lt;&gt; 会破坏这里的东西。如果您想避免此类问题,请尝试交换以下绑定:

[Table("Debug")] IAsyncCollector<Entry> tableBinding

到:

[Table("Debug")] CloudTable tableBinding

然后,不要使用tableBinding.AddAsync(),而是使用以下 sn-p:

var op = TableOperation.Insert(new Entry());
await tableBinding.ExecuteAsync(op);

使用这种方法,您应该能够捕获异常,而不会将其泄漏到 Functions 运行时。

【讨论】:

  • 这对我有用。注意:类Entry需要实现TableEntity。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 2022-01-02
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多