You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中从字符串获取异常类型并匹配对应错误处理策略?

刚好我之前处理过类似的Polly动态策略问题,给你一步步拆解解决:

如何从字符串异常名称获取类型并动态应用Polly策略?

你的核心问题有两个:一是从短字符串异常名(比如TimeoutException)正确获取对应的Type对象,二是根据配置动态生成Polly策略。下面逐个解决:

1. 解决从字符串获取异常类型的问题

你当前用Type.GetType(exceptionName)大概率失效,因为这个方法需要完整的类型全名(包含命名空间),比如System.TimeoutException,但你的JSON里只存了短名称。

可以写一个辅助方法,自动查找匹配的异常类型:

private Type GetExceptionType(string exceptionName)
{
    // 先尝试直接获取(如果传入的是完整类型名)
    var targetType = Type.GetType(exceptionName);
    if (targetType != null) return targetType;

    // 遍历所有已加载的程序集,找名称匹配且继承自Exception的类型
    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
        targetType = assembly.GetTypes()
            .FirstOrDefault(t => t.Name.Equals(exceptionName, StringComparison.OrdinalIgnoreCase) 
                                 && typeof(Exception).IsAssignableFrom(t));
        if (targetType != null) return targetType;
    }

    throw new ArgumentException($"未找到名为「{exceptionName}」的异常类型");
}

这个方法会先尝试直接匹配完整类型名,找不到就遍历所有已加载程序集,精准定位符合条件的异常类型。

2. 动态生成Polly策略

Polly的Handle<T>是泛型方法,没法直接用字符串类型调用,我们可以用非泛型的Handle方法+类型判断的方式来实现动态匹配,再结合你的配置生成对应策略。

完整重构后的代码

首先确保你的配置模型类正确:

public class RootObject
{
    public List<ExceptionMapper> ExceptionMappers { get; set; }
}

public class ExceptionMapper
{
    public string ExceptionName { get; set; }
    public string ExceptionType { get; set; }
    public string Policy { get; set; }
    public string WaitType { get; set; }
}

然后修改Execute方法,实现动态策略逻辑:

public void Execute(Action action, string exceptionName)
{
    var filePath = @"appsetting.json";
    var exceptionMapperJson = File.ReadAllText(filePath);
    var rootNode = JsonConvert.DeserializeObject<RootObject>(exceptionMapperJson);
    var exceptionNode = rootNode.ExceptionMappers.FirstOrDefault(e => 
        e.ExceptionName.Equals(exceptionName, StringComparison.OrdinalIgnoreCase));

    // 无匹配配置时执行空策略
    if (exceptionNode == null)
    {
        Policy.NoOp().Execute(action);
        return;
    }

    // 获取目标异常类型
    var targetExceptionType = GetExceptionType(exceptionNode.ExceptionName);
    ISyncPolicy policy = null;

    // 根据配置生成对应策略
    switch (exceptionNode.Policy)
    {
        case "WaitAndRetry":
            var retryCount = 3; // 建议把重试次数也放到JSON配置里
            if (exceptionNode.WaitType == "Linear")
            {
                policy = Policy
                    .Handle(ex => ex.GetType() == targetExceptionType)
                    .WaitAndRetry(retryCount, retryAttempt => TimeSpan.FromSeconds(retryAttempt));
            }
            // 可扩展其他等待策略,比如指数退避
            break;
        case "CircuitBreaker":
            policy = Policy
                .Handle(ex => ex.GetType() == targetExceptionType)
                .CircuitBreaker(2, TimeSpan.FromSeconds(30)); // 熔断阈值和时长也建议配置化
            break;
        case "LogOnly":
            // LogOnly策略:捕获异常后记录日志,再重新抛出
            policy = Policy
                .Handle(ex => ex.GetType() == targetExceptionType)
                .Retry(0, (ex, _) => 
                {
                    // 这里替换成你的日志逻辑,比如:
                    // Logger.LogError(ex, "捕获到需仅记录日志的异常");
                });
            break;
        default:
            policy = Policy.NoOp();
            break;
    }

    // 用生成的策略执行目标Action
    policy.Execute(action);
}

额外优化建议

  • 把重试次数、熔断阈值、等待时长这些参数也放到JSON配置里,让策略完全可配置
  • 缓存已获取的异常类型,避免每次都遍历程序集,提升性能
  • 给找不到类型的情况添加 fallback 逻辑,比如默认执行空策略

内容的提问来源于stack exchange,提问作者Developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:10:55