C#中处理API响应异常需结合分层策略与标准化响应规范
一、基础异常处理框架
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头部实现延迟重试 。