当所请求的 web api 遭遇 dns 解析失败 Name or service not know
,refit 就投降了,直接抛 null 引用异常
System.NullReferenceException: Object reference not set to an instance of an object.
at Refit.RequestBuilderImplementation.<>c__DisplayClass14_0`2.<<BuildCancellableTaskFuncForMethod>b__0>d.MoveNext() in /_/Refit/RequestBuilderImplementation.cs:line 298
查看对应的 298 行开源代码 RequestBuilderImplementation.cs:line#L298
throw await ApiException.Create("An error occured deserializing the response.", resp.RequestMessage!, resp.RequestMessage!.Method, resp, settings, ex);
当 dns 解析失败时,resp(类型是HttpResponseMessage)的值是 null,所以触发 NullReferenceException。
请问有没有什么变通方法借助 refit 的扩展能力帮助 refit 处理好这个异常情况,至少记录一下所请求的 api 地址,以便排查问题。
通过 Serilog.Exceptions.Refit
轻松解决了这个问题(我们使用了 serilog 日志组件)
安装 nuget 包
dotnet add package Serilog.Exceptions.Refit
Program 中添加 serilog 的 Enrich 配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(builder => builder.UseStartup<Startup>())
.UseSerilog(ConfigureLogger);
private static void ConfigureLogger(HostBuilderContext context, LoggerConfiguration loggerConfig)
{
loggerConfig.ReadFrom.Configuration(context.Configuration).Enrich
.WithExceptionDetails(new DestructuringOptionsBuilder()
.WithDefaultDestructurers()
.WithDestructurers(new[] { new ApiExceptionDestructurer() }));
}
日志输出
2023-01-30 17:30:10.941 [Warning] Failed to request: "Method: POST, RequestUri: 'http://blog_api/cache/post', Version: 1.1, Content: System.Net.Http.PushStreamContent, Headers:
{
Transfer-Encoding: chunked
traceparent: 00-6b93b9997b237fca1ec69e4834def6dd-8351e130911deee8-00
Content-Type: application/json; charset=utf-8
}"
Received response: null
System.Net.Http.HttpRequestException: Name or service not known (blog_api:80)
---> System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known
参考 https://github.com/RehanSaeed/Serilog.Exceptions#serilogexceptionsrefit