C#中处理API响应异常需结合分层策略与标准化响应规范

C#中处理API响应异常需结合分层策略与标准化响应规范

经验文章nimo972025-07-01 20:37:204A+A-


一、基础异常处理框架

1. 结构化异常捕获

使用try-catch-finally分层处理不同异常类型:

try

{

var response = await _httpClient.GetAsync(url);


response.EnsureSuccessStatusCode(); // 自动抛出非2xx异常

}

catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)

{

// 资源不存在异常(404)

_logger.LogWarning(#34;资源未找到: {ex.Message}");

return Results.NotFound();

}

catch (HttpRequestException ex) // 网络层异常

{

_logger.LogError(#34;网络请求失败: {ex.Message}");

return Results.StatusCode(500);

}

catch (JsonException ex) // JSON解析异常

{

_logger.LogError(#34;数据反序列化失败: {ex.Message}");

return Results.BadRequest("无效的响应格式");

}

finally

{

// 资源清理(如关闭数据库连接)

}


二、全局异常处理(Web API场景)

1. 自定义异常过滤器

实现IExceptionFilter统一处理控制器异常:

public class ApiExceptionFilter : IExceptionFilter

{

public void OnException(ExceptionContext context)

{

var error = new {

Code = "API_ERROR",

Message = context.Exception.Message,

Detail =
context.Exception.StackTrace // 仅开发环境暴露

};

context.Result = context.Exception switch

{

UnauthorizedAccessException => new ObjectResult(error) { StatusCode = 401 },

KeyNotFoundException => new ObjectResult(error) { StatusCode = 404 },

_ => new ObjectResult(error) { StatusCode = 500 } // 默认服务器错误

};

context.ExceptionHandled = true;

}

}

注册方式:

- 控制器级:[ServiceFilter(typeof(ApiExceptionFilter))]

- 全局级:services.AddControllers(options => options.Filters.Add<ApiExceptionFilter>())


三、高级策略优化

1. 重试与熔断机制

使用Polly库实现弹性策略:

var retryPolicy = Policy

.Handle<HttpRequestException>()

.Or<TaskCanceledException>()

.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));


var circuitBreaker = Policy

.Handle<TimeoutException>()

.CircuitBreakerAsync(5, TimeSpan.FromMinutes(1));


await Policy.WrapAsync(retryPolicy, circuitBreaker)

.ExecuteAsync(() => CallExternalApi());


2. 标准化错误响应

使用HttpError规范错误输出 :

if (!response.IsSuccessStatusCode)

{

var errorContent = await response.Content.ReadAsAsync<HttpError>();

throw new HttpResponseException(HttpStatusCode.BadRequest)

{

Content = new StringContent(JsonConvert.SerializeObject(new {

ErrorCode = "INVALID_REQUEST",

ErrorDetails = errorContent.Message

}))

};

}


四、关键实践原则

| 原则 | 实现方案 |

||--|

| 异常分类处理 | 区分网络异常(重试)、业务异常(返回4xx)、系统异常(日志+5xx) |

| 敏感信息保护 | 生产环境隐藏堆栈细节,仅返回安全错误码 |

| 日志结构化 | 记录异常类型、请求URL、时间戳、关联ID(便于链路追踪) |

| 超时控制 | HttpClient.Timeout = TimeSpan.FromSeconds(30); |

| 资源释放 | 对IDisposable对象(如数据库连接)使用using或finally块释放 |


五、调试与监控

1. 开发环境详细日志

启用详细错误模式(Global.asax):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy =


IncludeErrorDetailPolicy.Always; // 仅限开发环境

2. 生产环境监控

集成APM工具(如Application Insights)捕获:

- 异常频次与分布

- 慢请求追踪

- 依赖调用拓扑


> 提示:在Web API中,避免使用throw ex导致堆栈信息丢失,优先用throw保留原始异常链 。对于第三方API调用,需额外处理限流响应(429状态码),建议通过Retry-After头部实现延迟重试 。

点击这里复制本文地址 以上内容由nimo97整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

尼墨宝库 © All Rights Reserved.  蜀ICP备2024111239号-7