.NET如何创建模拟IHttpRequest实现超时返回401替代异常抛出
解决方案
无需修改上层业务处理逻辑,直接在HTTP请求封装层拦截超时异常,返回自定义模拟响应即可,具体实现如下:
1. 实现模拟响应类
PlainHttp的IHttpResponse为公开接口,无需依赖内置实现类,自定义类实现该接口即可,仅需为业务逻辑用到的属性赋值,其余属性保留默认值:
using PlainHttp; using System.Net; using System.Net.Http.Headers; public class FakeHttpResponse : IHttpResponse { public HttpStatusCode StatusCode { get; set; } = HttpStatusCode.Unauthorized; public string Body { get; set; } = string.Empty; // 对齐PlainHttp内置判定规则:2xx状态码标记为请求成功 public bool Succeeded => (int)StatusCode >= 200 && (int)StatusCode < 300; public HttpResponseMessage Message { get; set; } public TimeSpan ElapsedTime { get; set; } public IHttpRequest Request { get; set; } public Uri RequestUri { get; set; } public Version Version { get; set; } public HttpResponseHeaders Headers { get; set; } public void Dispose() { // 模拟响应无需要释放的非托管资源,空实现即可 } }
2. 下沉异常处理逻辑到基类
将异常拦截逻辑统一放在HttpBase中,避免每个子类重复编写try/catch逻辑:
using PlainHttp; using Sports.Services.Network; using HttpRequest = PlainHttp.HttpRequest; namespace Proj { public class HttpBase { public static IHttpRequest ProxiedRequest(string url) { IHttpRequest request = new HttpRequest(url) { Proxy = new Uri(Proxies.getRandomProxyConnection()), Timeout = TimeSpan.FromMilliseconds(5000) }; return request; } protected static async Task<IHttpResponse> SendAsync(IHttpRequest request) { try { return await request.SendAsync(); } catch (TimeoutException) { // 超时时返回401空响应,和普通请求失败逻辑对齐 return new FakeHttpResponse { Request = request, RequestUri = request.Uri, StatusCode = HttpStatusCode.Unauthorized, Body = string.Empty }; } // 如需统一处理代理连接失败、DNS解析错误等其他网络异常,在此处新增catch块即可 } } }
3. 调整子类请求方法
所有继承HttpBase的请求子类,调用基类的统一发送方法即可,无需单独处理异常:
public class HttpSiteA : HttpBase { public static async Task<IHttpResponse> Get(string url) { var request = ProxiedRequest(url); return await SendAsync(request); } }
实现效果
- 超时异常会在请求封装层被完全拦截,不会抛到上层业务逻辑,原有
ProcessSchedule和Task.WhenAll相关代码无需任何修改 - 超时场景返回的模拟响应
Succeeded属性为false,会自动走原有非200状态码的处理分支返回1,和普通请求失败的处理逻辑完全一致 - 后续如果需要调整超时后的返回状态码、响应内容,仅需修改基类catch块逻辑即可,全量站点自动生效
内容的提问来源于stack exchange,提问作者user3533755
相关产品推荐
相关产品推荐

