C#-为什么我的用于错误处理的包装函数没有捕获异常?

问题描述 投票:0回答:1

我正在使用以下内容概括包装功能:

public static class ErrorHandling
{
    public static void TryCatchErrors<TLogger>(ILogger<TLogger> logger, Action action, string? customMsg = null) => TryCatchErrors<TLogger, object>(logger, () => { action.Invoke(); return 0; }, customMsg);
    public static TOut TryCatchErrors<TLogger, TOut>(ILogger<TLogger> logger, Func<TOut> action, string? customMsg = null)
    {
        try 
        {
            if (logger == null) { throw new ArgumentNullException($"Got null for logger", $"Expected type ILogger<{typeof(TLogger).AssemblyQualifiedName}>!"); }
            if (action == null) { throw new ArgumentNullException($"Got null for action", $"Expected type Func<{typeof(TOut).AssemblyQualifiedName}>!"); }
            return action.Invoke(); 
        }
        catch (Exception e)
        {
            logger.LogError(e, customMsg ?? e.Message);
        }
    }
}

当我执行上述预期用法的以下示例时,我的包装函数无法捕获该错误:

    public static async Task DeleteRecords<TLog>(ILogger<TLog> _logger) =>
        await ErrorHandling.TryCatchErrors(_logger, async () =>
        {
            // Other functionality that might throw an unexpected error etc.

            throw new Exception();
        });

虽然我有可能在这里错过一些愚蠢的事情肯定是真实的,但我给人的印象是,这与一些我不了解并且一直在努力弄清自己的低级问题或担忧有关。] >

提前感谢!

我正在使用以下内容概括地包装功能:public static class ErrorHandling {public static void TryCatchErrors (ILogger logger,Action action,...

c# .net lambda error-handling wrapper
1个回答
3
投票

那是因为您要直接返回从参数Func<TOut> action返回的任务。这意味着可能无法在TryCatchErrors的try / catch内部执行任务。目前,它仅通过将任务传递给调用者来充当代理。

使其异步并在那里等待。通过使其异步并在方法内部等待它,您正在使其成为状态机的一部分。因此,try / catch也将是其中的一部分。

public async static TOut TryCatchErrors<TLogger, TOut>(ILogger<TLogger> logger, Func<TOut> action, string? customMsg = null)
{
    try 
    {
        if (logger == null) { throw new ArgumentNullException($"Got null for logger", $"Expected type ILogger<{typeof(TLogger).AssemblyQualifiedName}>!"); }
        if (action == null) { throw new ArgumentNullException($"Got null for action", $"Expected type Func<{typeof(TOut).AssemblyQualifiedName}>!"); }
        await action.Invoke(); 
    }
    catch (Exception e)
    {
        logger.LogError(e, customMsg ?? e.Message);
    }
}

我没有测试,但是我认为您应该将方法签名更改为:

public async static Task<TOut> TryCatchErrors<TLogger, TOut>(ILogger<TLogger> logger, Func<Task<TOut>> action, string? customMsg = null)
{
    try 
    {
        if (logger == null) { throw new ArgumentNullException($"Got null for logger", $"Expected type ILogger<{typeof(TLogger).AssemblyQualifiedName}>!"); }
        if (action == null) { throw new ArgumentNullException($"Got null for action", $"Expected type Func<{typeof(TOut).AssemblyQualifiedName}>!"); }
        await action.Invoke(); 
    }
    catch (Exception e)
    {
        logger.LogError(e, customMsg ?? e.Message);
    }
}

否则,您可能不被允许等待。

© www.soinside.com 2019 - 2024. All rights reserved.