From 70c56eadec0968e779b9a38e9cf6a891039388b0 Mon Sep 17 00:00:00 2001 From: Eric <5089238+emizzle@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:40:40 +1000 Subject: [PATCH] Add better error handling for non-200 codes Also add better json deserialization error handling --- DistTestCore/Codex/CodexAccess.cs | 2 +- DistTestCore/Http.cs | 42 +++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/DistTestCore/Codex/CodexAccess.cs b/DistTestCore/Codex/CodexAccess.cs index e2158ee..20665fe 100644 --- a/DistTestCore/Codex/CodexAccess.cs +++ b/DistTestCore/Codex/CodexAccess.cs @@ -71,7 +71,7 @@ namespace DistTestCore.Codex public string RequestStorage(CodexSalesRequestStorageRequest request, string contentId) { - return Http().HttpPostJson($"storage/request/{contentId}", request); + return Http().HttpPostJson($"storage/request/{contentId}", request); } public CodexStoragePurchase GetPurchaseStatus(string purchaseId) diff --git a/DistTestCore/Http.cs b/DistTestCore/Http.cs index 391dbc7..5e60632 100644 --- a/DistTestCore/Http.cs +++ b/DistTestCore/Http.cs @@ -1,5 +1,6 @@ using Logging; using Newtonsoft.Json; +using Serialization = Newtonsoft.Json.Serialization; using System.Net.Http.Headers; using System.Net.Http.Json; using Utils; @@ -47,11 +48,16 @@ namespace DistTestCore public TResponse HttpPostJson(string route, TRequest body) { - var json = HttpPostJson(route, body); + var response = HttpPostJson(route, body); + var json = Time.Wait(response.Content.ReadAsStringAsync()); + if(!response.IsSuccessStatusCode) { + throw new HttpRequestException(json); + } + Log(GetUrl() + route, json); return TryJsonDeserialize(json); } - public string HttpPostJson(string route, TRequest body) + public HttpResponseMessage HttpPostJson(string route, TRequest body) { return Retry(() => { @@ -59,10 +65,7 @@ namespace DistTestCore var url = GetUrl() + route; using var content = JsonContent.Create(body); Log(url, JsonConvert.SerializeObject(body)); - var result = Time.Wait(client.PostAsync(url, content)); - var str = Time.Wait(result.Content.ReadAsStringAsync()); - Log(url, str); - return str; + return Time.Wait(client.PostAsync(url, content)); }, $"HTTP-POST-JSON: {route}"); } @@ -95,15 +98,28 @@ namespace DistTestCore public T TryJsonDeserialize(string json) { - try - { - return JsonConvert.DeserializeObject(json)!; + var errors = new List(); + var deserialized = JsonConvert.DeserializeObject(json, new JsonSerializerSettings(){ + Error = delegate(object? sender, Serialization.ErrorEventArgs args) + { + if (args.CurrentObject == args.ErrorContext.OriginalObject) + { + errors.Add($""" + Member: '{args.ErrorContext.Member?.ToString() ?? ""}' + Path: {args.ErrorContext.Path} + Error: {args.ErrorContext.Error.Message} + """); + args.ErrorContext.Handled = true; + } + } + }); + if (errors.Count() > 0) { + throw new JsonSerializationException($"Failed to deserialize JSON '{json}' with exception(s): \n{string.Join("\n", errors)}"); } - catch (Exception exception) - { - var msg = $"Failed to deserialize JSON: '{json}' with exception: {exception}"; - throw new InvalidOperationException(msg, exception); + else if (deserialized == null) { + throw new JsonSerializationException($"Failed to deserialize JSON '{json}': resulting deserialized object is null"); } + return deserialized; } private string GetUrl()