From 84e05017ba5f218400a8aaaedb2ee6088e3c19a0 Mon Sep 17 00:00:00 2001
From: DismissedLight <1686188646@qq.com>
Date: Tue, 16 Jul 2024 17:30:25 +0800
Subject: [PATCH] impl #1720
---
.../Model/Calculable/CalculableOptions.cs | 14 --
.../Takumi/GameRecord/GameRecordClient.cs | 2 +-
.../Builder/HttpRequestMessageBuilder.cs | 10 +-
.../HttpRequestMessageBuilderExtension.cs | 136 ++++++++++++++----
.../HttpRequestMessageBuilderFactory.cs | 3 +-
5 files changed, 117 insertions(+), 48 deletions(-)
diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableOptions.cs b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableOptions.cs
index 4a8e54b9..b77c6898 100644
--- a/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableOptions.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Model/Calculable/CalculableOptions.cs
@@ -3,26 +3,12 @@
namespace Snap.Hutao.Model.Calculable;
-///
-/// 可计算物品选项
-///
internal readonly struct CalculableOptions
{
- ///
- /// 角色
- ///
public readonly ICalculableAvatar? Avatar;
- ///
- /// 武器
- ///
public readonly ICalculableWeapon? Weapon;
- ///
- /// 构造一个新的可计算物品选项
- ///
- /// 角色
- /// 武器
public CalculableOptions(ICalculableAvatar? avatar, ICalculableWeapon? weapon)
{
Avatar = avatar;
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs
index 8659d6e1..f018970d 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Takumi/GameRecord/GameRecordClient.cs
@@ -228,7 +228,7 @@ internal sealed partial class GameRecordClient : IGameRecordClient
.ConfigureAwait(false);
// We have a verification procedure to handle
- if (resp?.ReturnCode == (int)KnownReturnCode.CODE1034)
+ if (resp?.ReturnCode is (int)KnownReturnCode.CODE1034)
{
// Replace message
resp.Message = SH.WebIndexOrSpiralAbyssVerificationFailed;
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilder.cs
index fad7ec07..ebf5f004 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilder.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilder.cs
@@ -8,7 +8,7 @@ using System.Net.Http.Headers;
namespace Snap.Hutao.Web.Request.Builder;
-internal class HttpRequestMessageBuilder :
+internal sealed class HttpRequestMessageBuilder :
IBuilder,
IHttpRequestMessageBuilder,
IHttpHeadersBuilder,
@@ -22,12 +22,14 @@ internal class HttpRequestMessageBuilder :
IHttpMethodBuilder
{
private readonly HttpContentSerializer httpContentSerializer;
+ private readonly IServiceProvider serviceProvider;
private HttpRequestMessage httpRequestMessage;
- public HttpRequestMessageBuilder(HttpContentSerializer httpContentSerializer, HttpRequestMessage? httpRequestMessage = default)
+ public HttpRequestMessageBuilder(IServiceProvider serviceProvider, HttpContentSerializer httpContentSerializer, HttpRequestMessage? httpRequestMessage = default)
{
+ this.serviceProvider = serviceProvider;
this.httpContentSerializer = httpContentSerializer;
- this.httpRequestMessage = httpRequestMessage ?? new HttpRequestMessage();
+ this.httpRequestMessage = httpRequestMessage ?? new();
}
public HttpRequestMessage HttpRequestMessage
@@ -40,6 +42,8 @@ internal class HttpRequestMessageBuilder :
}
}
+ public IServiceProvider ServiceProvider { get => serviceProvider; }
+
public HttpContentSerializer HttpContentSerializer { get => httpContentSerializer; }
HttpContentHeaders IHttpHeadersBuilder.Headers
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs
index b834f07e..e5d643f6 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderExtension.cs
@@ -1,11 +1,14 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
+using Snap.Hutao.Service.Notification;
using Snap.Hutao.Web.Hutao.Response;
+using Snap.Hutao.Web.Response;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
+using System.Text;
namespace Snap.Hutao.Web.Request.Builder;
@@ -22,6 +25,10 @@ internal static class HttpRequestMessageBuilderExtension
internal static async ValueTask SendAsync(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
where TResult : class
{
+ StringBuilder messageBuilder = new();
+ messageBuilder.AppendLine(System.Globalization.CultureInfo.CurrentCulture, $"Host: {builder.RequestUri?.Host}");
+ bool showInfo = true;
+
try
{
using (builder.HttpRequestMessage)
@@ -29,51 +36,50 @@ internal static class HttpRequestMessageBuilderExtension
using (HttpResponseMessage message = await httpClient.SendAsync(builder.HttpRequestMessage, token).ConfigureAwait(false))
{
message.EnsureSuccessStatusCode();
- return await builder.HttpContentSerializer.DeserializeAsync(message.Content, token).ConfigureAwait(false);
+ showInfo = false;
+ return result = await builder.HttpContentSerializer.DeserializeAsync(message.Content, token).ConfigureAwait(false);
}
}
}
catch (HttpRequestException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
-
- if (ex.StatusCode is HttpStatusCode.BadGateway)
+ if (TryHandleHttp502HutaoResponseSpecialCase(ex, out TResult? result))
{
- Type resultType = typeof(TResult);
-
- if (resultType == typeof(HutaoResponse))
- {
- return Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default) as TResult;
- }
-
- if (resultType.IsConstructedGenericType && resultType.GetGenericTypeDefinition() == typeof(HutaoResponse<>))
- {
- return Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default, default) as TResult;
- }
+ return result;
}
- return default;
+ ProcessException(messageBuilder, ex);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (IOException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
- return default;
+ ProcessException(messageBuilder, ex);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (JsonException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
- return default;
+ ProcessException(messageBuilder, ex);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (HttpContentSerializationException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
- return default;
+ ProcessException(messageBuilder, ex);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (SocketException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
- return default;
+ ProcessException(messageBuilder, ex);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
+ finally
+ {
+ if (showInfo)
+ {
+ builder.ServiceProvider.GetRequiredService().Error(messageBuilder.ToString());
+ }
+ }
+
+ return default;
}
internal static void Send(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger)
@@ -86,23 +92,95 @@ internal static class HttpRequestMessageBuilderExtension
}
catch (HttpRequestException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (IOException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (JsonException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (HttpContentSerializationException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
}
catch (SocketException ex)
{
- logger.LogWarning(ex, RequestErrorMessage, builder.HttpRequestMessage.RequestUri);
+ logger.LogWarning(ex, RequestErrorMessage, builder.RequestUri);
+ }
+ }
+
+ private static bool TryHandleHttp502HutaoResponseSpecialCase(HttpRequestException ex, out TResult? result)
+ where TResult : class
+ {
+ result = default;
+
+ if (ex.StatusCode is HttpStatusCode.BadGateway)
+ {
+ Type resultType = typeof(TResult);
+
+ if (resultType == typeof(HutaoResponse))
+ {
+ // HutaoResponse(int returnCode, string message, string? localizationKey)
+ result = Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default) as TResult;
+ return true;
+ }
+
+ if (resultType.IsConstructedGenericType && resultType.GetGenericTypeDefinition() == typeof(HutaoResponse<>))
+ {
+ // HutaoResponse(int returnCode, string message, TData? data, string? localizationKey)
+ result = Activator.CreateInstance(resultType, 502, SH.WebHutaoServiceUnAvailable, default, default) as TResult;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ [SuppressMessage("", "CA1305")]
+ private static void ProcessException(StringBuilder builder, Exception exception)
+ {
+ if (exception is HttpRequestException hre)
+ {
+ builder
+ .AppendLine($"{nameof(HttpRequestException)}: Status Code: {hre.StatusCode} Error: {hre.HttpRequestError}")
+ .AppendLine(hre.Message);
+ }
+
+ if (exception is IOException ioe)
+ {
+ builder
+ .AppendLine($"{nameof(IOException)}: 0x{ioe.HResult:X8}")
+ .AppendLine(ioe.Message);
+ }
+
+ if (exception is JsonException je)
+ {
+ builder
+ .AppendLine($"{nameof(JsonException)}: Path: {je.Path} at Line: {je.LineNumber} Position: {je.BytePositionInLine}")
+ .AppendLine(je.Message);
+ }
+
+ if (exception is HttpContentSerializationException hcse)
+ {
+ builder
+ .AppendLine($"{nameof(HttpContentSerializationException)}:")
+ .AppendLine(hcse.Message);
+ }
+
+ if (exception is SocketException se)
+ {
+ builder
+ .AppendLine($"{nameof(SocketException)}: Error: {se.SocketErrorCode}")
+ .AppendLine(se.Message);
+ }
+
+ if (exception.InnerException is { } inner)
+ {
+ builder.AppendLine(new string('-', 40));
+ ProcessException(builder, inner);
}
}
}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderFactory.cs b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderFactory.cs
index e6465871..6385dcc1 100644
--- a/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderFactory.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Web/Request/Builder/HttpRequestMessageBuilderFactory.cs
@@ -10,9 +10,10 @@ namespace Snap.Hutao.Web.Request.Builder;
internal sealed partial class HttpRequestMessageBuilderFactory : IHttpRequestMessageBuilderFactory
{
private readonly JsonHttpContentSerializer jsonHttpContentSerializer;
+ private readonly IServiceProvider serviceProvider;
public HttpRequestMessageBuilder Create()
{
- return new(jsonHttpContentSerializer);
+ return new(serviceProvider, jsonHttpContentSerializer);
}
}
\ No newline at end of file