This commit is contained in:
DismissedLight
2024-07-16 17:30:25 +08:00
parent 2c139a1ff6
commit 84e05017ba
5 changed files with 117 additions and 48 deletions

View File

@@ -3,26 +3,12 @@
namespace Snap.Hutao.Model.Calculable;
/// <summary>
/// 可计算物品选项
/// </summary>
internal readonly struct CalculableOptions
{
/// <summary>
/// 角色
/// </summary>
public readonly ICalculableAvatar? Avatar;
/// <summary>
/// 武器
/// </summary>
public readonly ICalculableWeapon? Weapon;
/// <summary>
/// 构造一个新的可计算物品选项
/// </summary>
/// <param name="avatar">角色</param>
/// <param name="weapon">武器</param>
public CalculableOptions(ICalculableAvatar? avatar, ICalculableWeapon? weapon)
{
Avatar = avatar;

View File

@@ -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;

View File

@@ -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<HttpHeaders>,
@@ -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<HttpContentHeaders>.Headers

View File

@@ -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<TResult?> SendAsync<TResult>(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<TResult>(message.Content, token).ConfigureAwait(false);
showInfo = false;
return result = await builder.HttpContentSerializer.DeserializeAsync<TResult>(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<IInfoBarService>().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<TResult>(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<TData>(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);
}
}
}

View File

@@ -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);
}
}