如何在异步 Azure 函数 HTTP 触发函数中捕获 Azure Table 抛出的异常
How to catch an Exception throw by Azure Table in an async Azure Function HTTP Triggered function
我有一个 Azure Function HTTP 触发函数,它写入 Azure Table,可能以重复的条目结尾。我注意到,即使我 try/catch'd 了整个函数,函数运行器仍然会出现异常 "leaked",从而返回 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{}
代码,但仍然 returns 一个 HTTP 500(!)
- 在 Application Insights 中,每个请求有两个 table 依赖调用(不应该发生,文档说 table 没有自动重试)
您的 try/catch 块应该如下所示以捕获所有错误
try
{
}
catch (StorageException)
{
return new OkObjectResult("This passes test");
}
catch (Exception ex)
{
// return different error code
}
我想,使用 IAsyncCollector<>
会破坏这里的东西。如果您想避免此类问题,请尝试交换以下绑定:
[Table("Debug")] IAsyncCollector<Entry> tableBinding
至:
[Table("Debug")] CloudTable tableBinding
然后,不要使用 tableBinding.AddAsync()
,而是使用以下代码段:
var op = TableOperation.Insert(new Entry());
await tableBinding.ExecuteAsync(op);
使用这种方法,您应该能够捕获异常,而不会将其泄露给 Functions 运行时。
我有一个 Azure Function HTTP 触发函数,它写入 Azure Table,可能以重复的条目结尾。我注意到,即使我 try/catch'd 了整个函数,函数运行器仍然会出现异常 "leaked",从而返回 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{}
代码,但仍然 returns 一个 HTTP 500(!) - 在 Application Insights 中,每个请求有两个 table 依赖调用(不应该发生,文档说 table 没有自动重试)
您的 try/catch 块应该如下所示以捕获所有错误
try
{
}
catch (StorageException)
{
return new OkObjectResult("This passes test");
}
catch (Exception ex)
{
// return different error code
}
我想,使用 IAsyncCollector<>
会破坏这里的东西。如果您想避免此类问题,请尝试交换以下绑定:
[Table("Debug")] IAsyncCollector<Entry> tableBinding
至:
[Table("Debug")] CloudTable tableBinding
然后,不要使用 tableBinding.AddAsync()
,而是使用以下代码段:
var op = TableOperation.Insert(new Entry());
await tableBinding.ExecuteAsync(op);
使用这种方法,您应该能够捕获异常,而不会将其泄露给 Functions 运行时。