У меня есть функция 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 2.0 (для .NET Core).
Нажмите /api/debug дважды или более, и вы увидите:
catch{} введен, но все равно возвращает HTTP 500(!)Также возможно, но он сказал, что поток входит в блок catch и все равно сообщает 500.
@Charleh Я уже проводил эксперименты, прежде чем пришел сюда, чтобы спросить, и перехват Exception просто не работает. Предоставленный код является минимальной версией для воспроизведения проблемы, это не то, что я написал в реальном проекте.





Ваш блок try/catch должен выглядеть следующим образом, чтобы перехватывать все ошибки.
try
{
}
catch (StorageException)
{
return new OkObjectResult("This passes test");
}
catch (Exception ex)
{
// return different error code
}
Предоставленный код является лишь минимальной версией для воспроизведения проблемы. В моем собственном коде я пробовал несколько способов, включая перехват общего исключения, и у меня есть обширное ведение журнала, поэтому я почти уверен, что StorageException является единственным типом исключения.
Я думаю, что использование IAsyncCollector<> здесь все ломает. Если вы хотите избежать подобных проблем, попробуйте поменять следующую привязку:
[Table("Debug")] IAsyncCollector<Entry> tableBinding
к:
[Table("Debug")] CloudTable tableBinding
Затем вместо использования tableBinding.AddAsync() используйте следующий фрагмент:
var op = TableOperation.Insert(new Entry());
await tableBinding.ExecuteAsync(op);
При таком подходе вы должны иметь возможность перехватывать исключение, не пропуская его в среду выполнения функций.
Это работает для меня. Примечание: класс Entry должен реализовать TableEntity.
Вы не перехватываете все типы исключений, поэтому, конечно, исключение может просочиться. Вы на 100% уверены, что не пропустили исключение из-за отсутствия общего блока
system.exceptioncatch?