我正在使用以下内容概括包装功能:
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
那是因为您要直接返回从参数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);
}
}
否则,您可能不被允许等待。