Skip to content

Commit

Permalink
Handle unexpected HTTP responses
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuaflanagan committed Jun 28, 2024
1 parent 561e3af commit f1f6d96
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
69 changes: 69 additions & 0 deletions ShipEngine.Tests/ShipEngineClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
namespace ShipEngineTest
{
using ShipEngineSDK;
using ShipEngineSDK.VoidLabelWithLabelId;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;

public class ShipEngineClientTests
{
[Fact]
public async Task FailureWithShipengineResponseThrowsPopulatedShipEngineException()
{
var config = new Config(apiKey: "test", timeout: TimeSpan.FromSeconds(0.5));
var mockShipEngineFixture = new MockShipEngineFixture(config);
var shipengine = mockShipEngineFixture.ShipEngine;


string requestId = "12345";
string message = "Request body cannot be empty.";
var responseBody = string.Format(
@"
{{
""request_id"": ""{0}"",
""errors"": [
{{
""error_source"": ""shipengine"",
""error_type"": ""validation"",
""error_code"": ""request_body_required"",
""message"": ""{1}""
}}
]
}}", requestId, message);


mockShipEngineFixture.StubRequest(HttpMethod.Post, "/v1/something", System.Net.HttpStatusCode.BadRequest,
responseBody);
var ex = await Assert.ThrowsAsync<ShipEngineException>(
async () => await shipengine.SendHttpRequestAsync<Result>(HttpMethod.Post, "/v1/something", "",
mockShipEngineFixture.HttpClient, config)
);

Assert.Equal(requestId, ex.RequestId);
Assert.Equal(message, ex.Message);
Assert.Equal(ErrorSource.Shipengine, ex.ErrorSource);
Assert.Equal(ErrorType.Validation, ex.ErrorType);
Assert.Equal(ErrorCode.RequestBodyRequired, ex.ErrorCode);
}

[Fact]
public async Task FailureWithoutShipengineResponseThrowsHttpException()
{
var config = new Config(apiKey: "test", timeout: TimeSpan.FromSeconds(0.5));
var mockShipEngineFixture = new MockShipEngineFixture(config);
var shipengine = mockShipEngineFixture.ShipEngine;

var responseBody = @"<h1>Bad Gateway</h1>";
mockShipEngineFixture.StubRequest(HttpMethod.Post, "/v1/something", System.Net.HttpStatusCode.BadGateway,
responseBody);
var ex = await Assert.ThrowsAsync<HttpRequestException>(
async () => await shipengine.SendHttpRequestAsync<Result>(HttpMethod.Post, "/v1/something", "",
mockShipEngineFixture.HttpClient, config)
);

Assert.Contains("502", ex.Message);
}
}
}
10 changes: 9 additions & 1 deletion ShipEngine/ShipEngineClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,15 @@ private async Task<T> DeserializedResultOrThrow<T>(HttpResponseMessage response)

if (!response.IsSuccessStatusCode)
{
var deserializedError = JsonSerializer.Deserialize<ShipEngineAPIError>(contentString, JsonSerializerOptions);
ShipEngineAPIError? deserializedError = null;
try
{
deserializedError =
JsonSerializer.Deserialize<ShipEngineAPIError>(contentString, JsonSerializerOptions);
}
catch (JsonException)
{
}

// Throw Generic HttpClient Error if unable to deserialize to a ShipEngineException
if (deserializedError == null)
Expand Down

0 comments on commit f1f6d96

Please sign in to comment.