diff --git a/Gw2Sharp.Tests/WebApi/Exceptions/RequestExceptionTests.cs b/Gw2Sharp.Tests/WebApi/Exceptions/RequestExceptionTests.cs index ed7628a28..93376c1cf 100644 --- a/Gw2Sharp.Tests/WebApi/Exceptions/RequestExceptionTests.cs +++ b/Gw2Sharp.Tests/WebApi/Exceptions/RequestExceptionTests.cs @@ -1,6 +1,7 @@ using System; using Gw2Sharp.WebApi.Exceptions; using Gw2Sharp.WebApi.Http; +using Gw2Sharp.WebApi.V2.Models; using NSubstitute; using Xunit; @@ -12,7 +13,7 @@ public class RequestExceptionTests public void ConstructorTest() { var request = Substitute.For(); - var response = Substitute.For(); + var response = Substitute.For>(); var innerException = new NotImplementedException(); string message = "test exception"; diff --git a/Gw2Sharp.Tests/WebApi/Exceptions/UnexpectedStatusExceptionTests.cs b/Gw2Sharp.Tests/WebApi/Exceptions/UnexpectedStatusExceptionTests.cs index ff08d05aa..0a19a4642 100644 --- a/Gw2Sharp.Tests/WebApi/Exceptions/UnexpectedStatusExceptionTests.cs +++ b/Gw2Sharp.Tests/WebApi/Exceptions/UnexpectedStatusExceptionTests.cs @@ -1,5 +1,6 @@ using Gw2Sharp.WebApi.Exceptions; using Gw2Sharp.WebApi.Http; +using Gw2Sharp.WebApi.V2.Models; using NSubstitute; using Xunit; @@ -11,7 +12,7 @@ public class UnexpectedStatusExceptionTests public void ConstructorTest() { var request = Substitute.For(); - var response = Substitute.For(); + var response = Substitute.For>(); string message = "test exception"; var exception = new UnexpectedStatusException(request, response); diff --git a/Gw2Sharp.Tests/WebApi/Middleware/ExceptionMiddlewareTests.cs b/Gw2Sharp.Tests/WebApi/Middleware/ExceptionMiddlewareTests.cs index 00cf7aea3..1fb5c0cfa 100644 --- a/Gw2Sharp.Tests/WebApi/Middleware/ExceptionMiddlewareTests.cs +++ b/Gw2Sharp.Tests/WebApi/Middleware/ExceptionMiddlewareTests.cs @@ -6,7 +6,6 @@ using Gw2Sharp.WebApi.Exceptions; using Gw2Sharp.WebApi.Http; using Gw2Sharp.WebApi.Middleware; -using Gw2Sharp.WebApi.V2.Models; using NSubstitute; using Xunit; @@ -46,7 +45,7 @@ public async Task ExceptionRequestTest(string errorText, HttpStatusCode statusCo using (new AssertionScope()) { Func act = () => middleware.OnRequestAsync(context, (c, t) => Task.FromResult(response)); - var exception = (await act.Should().ThrowAsync>() + var exception = (await act.Should().ThrowAsync() .WithMessage(errorText)) .Which; @@ -71,7 +70,7 @@ public async Task ExceptionNoJsonRequestTest(string body, HttpStatusCode statusC using (new AssertionScope()) { Func act = () => middleware.OnRequestAsync(context, (c, t) => Task.FromResult(response)); - var exception = (await act.Should().ThrowAsync>() + var exception = (await act.Should().ThrowAsync() .WithMessage(body)) .Which; @@ -83,13 +82,14 @@ public async Task ExceptionNoJsonRequestTest(string body, HttpStatusCode statusC [Fact] public async Task UnexpectedStatusExceptionRequestTest() { - const string MESSAGE = "{\"error\":\"Some nice error message\"}"; + const string MESSAGE = "Some nice error message"; + const string JSON = "{\"error\":\"" + MESSAGE + "\"}"; var connection = Substitute.For(); var request = Substitute.For(); var context = new MiddlewareContext(connection, request); var response = Substitute.For(); - response.Content.Returns(MESSAGE); + response.Content.Returns(JSON); response.StatusCode.Returns((HttpStatusCode)499); var middleware = new ExceptionMiddleware(); @@ -97,7 +97,7 @@ public async Task UnexpectedStatusExceptionRequestTest() Func act = () => middleware.OnRequestAsync(context, (c, t) => Task.FromResult(response)); (await act.Should().ThrowAsync()) .WithMessage(MESSAGE) - .Which.Response?.Content.Should().Be(MESSAGE); + .Which.Response?.Content.Message.Should().Be(MESSAGE); } } } diff --git a/Gw2Sharp/WebApi/Exceptions/AuthorizationRequiredException.cs b/Gw2Sharp/WebApi/Exceptions/AuthorizationRequiredException.cs index 1e684f8cc..d41da4ad2 100644 --- a/Gw2Sharp/WebApi/Exceptions/AuthorizationRequiredException.cs +++ b/Gw2Sharp/WebApi/Exceptions/AuthorizationRequiredException.cs @@ -7,8 +7,8 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails to authorize (code 403). /// - /// - public class AuthorizationRequiredException : UnexpectedStatusException + /// + public class AuthorizationRequiredException : UnexpectedStatusException { /// /// Creates a new . @@ -18,7 +18,7 @@ public class AuthorizationRequiredException : UnexpectedStatusExceptionThe error. /// , or is null. public AuthorizationRequiredException(IWebApiRequest request, IWebApiResponse response, AuthorizationError error) : - base(request, response, response?.Content.Message ?? string.Empty) + base(request, response) { this.AuthorizationError = error; } diff --git a/Gw2Sharp/WebApi/Exceptions/BadRequestException.cs b/Gw2Sharp/WebApi/Exceptions/BadRequestException.cs index e06891986..318560785 100644 --- a/Gw2Sharp/WebApi/Exceptions/BadRequestException.cs +++ b/Gw2Sharp/WebApi/Exceptions/BadRequestException.cs @@ -7,8 +7,8 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a bad request was done (code 400). /// - /// - public class BadRequestException : UnexpectedStatusException + /// + public class BadRequestException : UnexpectedStatusException { /// /// Creates a new . @@ -18,7 +18,7 @@ public class BadRequestException : UnexpectedStatusException /// The error. /// or is null. public BadRequestException(IWebApiRequest request, IWebApiResponse response, BadRequestError error) : - base(request, response, response?.Content.Message ?? string.Empty) + base(request, response) { this.BadRequestError = error; } diff --git a/Gw2Sharp/WebApi/Exceptions/InvalidAccessTokenException.cs b/Gw2Sharp/WebApi/Exceptions/InvalidAccessTokenException.cs index ed597967f..40de5ca2e 100644 --- a/Gw2Sharp/WebApi/Exceptions/InvalidAccessTokenException.cs +++ b/Gw2Sharp/WebApi/Exceptions/InvalidAccessTokenException.cs @@ -7,7 +7,7 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails to authorize due to an invalid API key (code 403). /// - /// + /// public class InvalidAccessTokenException : AuthorizationRequiredException { /// @@ -17,6 +17,7 @@ public class InvalidAccessTokenException : AuthorizationRequiredException /// The response. /// or is null. public InvalidAccessTokenException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, AuthorizationError.InvalidKey) { } + base(request, response, AuthorizationError.InvalidKey) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/MembershipRequiredException.cs b/Gw2Sharp/WebApi/Exceptions/MembershipRequiredException.cs index c32953fd1..2e8285bfb 100644 --- a/Gw2Sharp/WebApi/Exceptions/MembershipRequiredException.cs +++ b/Gw2Sharp/WebApi/Exceptions/MembershipRequiredException.cs @@ -7,7 +7,7 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails to authorize due to the owner of the API key not being a member of the guild (code 403). /// - /// + /// public class MembershipRequiredException : AuthorizationRequiredException { /// @@ -17,6 +17,7 @@ public class MembershipRequiredException : AuthorizationRequiredException /// The response. /// or is null. public MembershipRequiredException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, AuthorizationError.MembershipRequired) { } + base(request, response, AuthorizationError.MembershipRequired) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/MissingScopesException.cs b/Gw2Sharp/WebApi/Exceptions/MissingScopesException.cs index 508ee5d0c..9299b85a6 100644 --- a/Gw2Sharp/WebApi/Exceptions/MissingScopesException.cs +++ b/Gw2Sharp/WebApi/Exceptions/MissingScopesException.cs @@ -7,7 +7,7 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails to authorize due to missing permissions (code 403). /// - /// + /// public class MissingScopesException : AuthorizationRequiredException { /// @@ -17,6 +17,7 @@ public class MissingScopesException : AuthorizationRequiredException /// The response. /// or is null. public MissingScopesException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, AuthorizationError.MissingScopes) { } + base(request, response, AuthorizationError.MissingScopes) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/NotFoundException.cs b/Gw2Sharp/WebApi/Exceptions/NotFoundException.cs index 19deb56be..37b1f2b82 100644 --- a/Gw2Sharp/WebApi/Exceptions/NotFoundException.cs +++ b/Gw2Sharp/WebApi/Exceptions/NotFoundException.cs @@ -7,8 +7,8 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a response cannot be found (code 404). /// - /// - public class NotFoundException : UnexpectedStatusException + /// + public class NotFoundException : UnexpectedStatusException { /// /// Creates a new . @@ -17,6 +17,7 @@ public class NotFoundException : UnexpectedStatusException /// The response. /// or is null. public NotFoundException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, response?.Content.Message ?? string.Empty) { } + base(request, response) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/RequestException.cs b/Gw2Sharp/WebApi/Exceptions/RequestException.cs index 8e723071e..511e96e9b 100644 --- a/Gw2Sharp/WebApi/Exceptions/RequestException.cs +++ b/Gw2Sharp/WebApi/Exceptions/RequestException.cs @@ -1,12 +1,13 @@ using System; using Gw2Sharp.WebApi.Http; +using Gw2Sharp.WebApi.V2.Models; namespace Gw2Sharp.WebApi.Exceptions { /// /// A generic request exception used for the web API. /// - public class RequestException : RequestException + public class RequestException : Exception { /// /// Creates a new . @@ -15,7 +16,8 @@ public class RequestException : RequestException /// The message. /// or is null. public RequestException(IWebApiRequest request, string message) : - base(request, message) { } + this(request, null, message, null) + { } /// /// Creates a new . @@ -24,8 +26,9 @@ public RequestException(IWebApiRequest request, string message) : /// The response. /// The message. /// or is null. - public RequestException(IWebApiRequest request, IWebApiResponse? response, string message) : - base(request, response, message) { } + public RequestException(IWebApiRequest request, IWebApiResponse? response, string message) : + this(request, response, message, null) + { } /// /// Creates a new . @@ -35,7 +38,8 @@ public RequestException(IWebApiRequest request, IWebApiResponse? respons /// The inner exception. /// or is null. public RequestException(IWebApiRequest request, string message, Exception? innerException) : - base(request, message, innerException) { } + this(request, null, message, innerException) + { } /// /// Creates a new . @@ -44,55 +48,7 @@ public RequestException(IWebApiRequest request, string message, Exception? inner /// The response. /// The message. /// The inner exception. - /// or is null. - public RequestException(IWebApiRequest request, IWebApiResponse? response, string message, Exception innerException) : - base(request, response, message, innerException) { } - } - - - /// - /// A generic request exception used for the web API. - /// - /// The response object. - public class RequestException : Exception - { - /// - /// Creates a new . - /// - /// The original request. - /// The message. - /// or is null. - public RequestException(IWebApiRequest request, string message) : - this(request, null, message, null) { } - - /// - /// Creates a new . - /// - /// The original request. - /// The response. - /// The message. - /// or is null. - public RequestException(IWebApiRequest request, IWebApiResponse? response, string message) : - this(request, response, message, null) { } - - /// - /// Creates a new . - /// - /// The original request. - /// The message. - /// The inner exception. - /// or is null. - public RequestException(IWebApiRequest request, string message, Exception? innerException) : - this(request, null, message, innerException) { } - - /// - /// Creates a new . - /// - /// The original request. - /// The response. - /// The message. - /// The inner exception. - public RequestException(IWebApiRequest request, IWebApiResponse? response, string message, Exception? innerException) : + public RequestException(IWebApiRequest request, IWebApiResponse? response, string message, Exception? innerException) : base(message, innerException) { this.Request = request ?? throw new ArgumentNullException(nameof(request)); @@ -107,6 +63,6 @@ public RequestException(IWebApiRequest request, IWebApiResponse? resp /// /// Gets the response. /// - public IWebApiResponse? Response { get; } + public IWebApiResponse? Response { get; } } } diff --git a/Gw2Sharp/WebApi/Exceptions/RestrictedToGuildLeadersException.cs b/Gw2Sharp/WebApi/Exceptions/RestrictedToGuildLeadersException.cs index a0fb350d7..bb91f9e79 100644 --- a/Gw2Sharp/WebApi/Exceptions/RestrictedToGuildLeadersException.cs +++ b/Gw2Sharp/WebApi/Exceptions/RestrictedToGuildLeadersException.cs @@ -7,7 +7,7 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails to authorize due to the owner not being a guild leader (code 403). /// - /// + /// public class RestrictedToGuildLeadersException : AuthorizationRequiredException { /// @@ -17,6 +17,7 @@ public class RestrictedToGuildLeadersException : AuthorizationRequiredException /// The response. /// or is null. public RestrictedToGuildLeadersException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, AuthorizationError.AccessRestrictedToGuildLeaders) { } + base(request, response, AuthorizationError.AccessRestrictedToGuildLeaders) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/ServerErrorException.cs b/Gw2Sharp/WebApi/Exceptions/ServerErrorException.cs index 6ad73db98..2cb8a570a 100644 --- a/Gw2Sharp/WebApi/Exceptions/ServerErrorException.cs +++ b/Gw2Sharp/WebApi/Exceptions/ServerErrorException.cs @@ -7,8 +7,8 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails due to an internal server error (code 500). /// - /// - public class ServerErrorException : UnexpectedStatusException + /// + public class ServerErrorException : UnexpectedStatusException { /// /// Creates a new . @@ -17,6 +17,7 @@ public class ServerErrorException : UnexpectedStatusException /// The response. /// or is null. public ServerErrorException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, response?.Content.Message ?? string.Empty) { } + base(request, response) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/ServiceUnavailableException.cs b/Gw2Sharp/WebApi/Exceptions/ServiceUnavailableException.cs index e861211f5..d3849514b 100644 --- a/Gw2Sharp/WebApi/Exceptions/ServiceUnavailableException.cs +++ b/Gw2Sharp/WebApi/Exceptions/ServiceUnavailableException.cs @@ -7,8 +7,8 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails due to the service being unavailable (code 500). /// - /// - public class ServiceUnavailableException : UnexpectedStatusException + /// + public class ServiceUnavailableException : UnexpectedStatusException { /// /// Creates a new . @@ -17,6 +17,7 @@ public class ServiceUnavailableException : UnexpectedStatusExceptionThe response. /// or is null. public ServiceUnavailableException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, response?.Content.Message ?? string.Empty) { } + base(request, response) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/TooManyRequestsException.cs b/Gw2Sharp/WebApi/Exceptions/TooManyRequestsException.cs index 37d05baef..129261b53 100644 --- a/Gw2Sharp/WebApi/Exceptions/TooManyRequestsException.cs +++ b/Gw2Sharp/WebApi/Exceptions/TooManyRequestsException.cs @@ -7,8 +7,8 @@ namespace Gw2Sharp.WebApi.Exceptions /// /// A web API specific exception that's used when a request fails due to issuing too many requests in a short period of time (code 429). /// - /// - public class TooManyRequestsException : UnexpectedStatusException + /// + public class TooManyRequestsException : UnexpectedStatusException { /// /// Creates a new . @@ -17,6 +17,7 @@ public class TooManyRequestsException : UnexpectedStatusException /// The response. /// or is null. public TooManyRequestsException(IWebApiRequest request, IWebApiResponse response) : - base(request, response, response?.Content.Message ?? string.Empty) { } + base(request, response) + { } } } diff --git a/Gw2Sharp/WebApi/Exceptions/UnexpectedStatusException.cs b/Gw2Sharp/WebApi/Exceptions/UnexpectedStatusException.cs index 818493073..bab5a93e5 100644 --- a/Gw2Sharp/WebApi/Exceptions/UnexpectedStatusException.cs +++ b/Gw2Sharp/WebApi/Exceptions/UnexpectedStatusException.cs @@ -1,5 +1,6 @@ using System; using Gw2Sharp.WebApi.Http; +using Gw2Sharp.WebApi.V2.Models; namespace Gw2Sharp.WebApi.Exceptions { @@ -14,8 +15,9 @@ public class UnexpectedStatusException : RequestException /// The original request. /// The response. /// or is null. - public UnexpectedStatusException(IWebApiRequest request, IWebApiResponse response) : - this(request, response, $"Unexpected HTTP status code: {(int?)response?.StatusCode ?? 0}") { } + public UnexpectedStatusException(IWebApiRequest request, IWebApiResponse response) : + this(request, response, FormatMessage(response)) + { } /// /// Creates a new . @@ -24,31 +26,20 @@ public UnexpectedStatusException(IWebApiRequest request, IWebApiResponse /// The response. /// The message. /// or is null. - public UnexpectedStatusException(IWebApiRequest request, IWebApiResponse? response, string message) : - base(request, response, message) { } - } + public UnexpectedStatusException(IWebApiRequest request, IWebApiResponse? response, string message) : + base(request, response, message) + { } - /// - /// An exception that's used when an HTTP request returned an unexpected status code, e.g. a non-successful one. - /// - public class UnexpectedStatusException : RequestException - { - /// - /// Creates a new . - /// - /// The original request. - /// The response. - public UnexpectedStatusException(IWebApiRequest request, IWebApiResponse response) : - this(request, response, $"Unexpected HTTP status code: {(int?)response?.StatusCode ?? 0}") { } - /// - /// Creates a new . - /// - /// The original request. - /// The response. - /// The message. - /// or is null. - public UnexpectedStatusException(IWebApiRequest request, IWebApiResponse? response, string message) : - base(request, response, message) { } + private static string FormatMessage(IWebApiResponse response) + { + if (response is null) + return "Unexpected response (no additional information available)"; + + if (!string.IsNullOrEmpty(response.Content?.Message)) + return response.Content.Message; + + return $"Unexpected HTTP status code: {(int)response.StatusCode}"; + } } } diff --git a/Gw2Sharp/WebApi/Http/IWebApiResponse.cs b/Gw2Sharp/WebApi/Http/IWebApiResponse.cs index b5f3007f6..a54bedc2c 100644 --- a/Gw2Sharp/WebApi/Http/IWebApiResponse.cs +++ b/Gw2Sharp/WebApi/Http/IWebApiResponse.cs @@ -11,12 +11,6 @@ namespace Gw2Sharp.WebApi.Http /// public interface IWebApiResponse : IWebApiResponse { - /// - /// Creates a copy of the request. - /// This deep copies . - /// - /// The cloned response. - new IWebApiResponse Copy(); } /// @@ -44,13 +38,6 @@ public interface IWebApiResponse /// The response headers. /// IDictionary ResponseHeaders { get; } - - /// - /// Creates a copy of the request. - /// This deep copies , but copies by reference. - /// - /// The cloned response. - IWebApiResponse Copy(); } diff --git a/Gw2Sharp/WebApi/Http/WebApiResponse.cs b/Gw2Sharp/WebApi/Http/WebApiResponse.cs index 1cb5f028d..43058fc1f 100644 --- a/Gw2Sharp/WebApi/Http/WebApiResponse.cs +++ b/Gw2Sharp/WebApi/Http/WebApiResponse.cs @@ -39,10 +39,6 @@ public WebApiResponse(string content, HttpStatusCode? statusCode, CacheState cac /// is null. public WebApiResponse(string content, HttpStatusCode? statusCode, CacheState cacheState, IEnumerable>? responseHeaders) : base(content, statusCode, cacheState, responseHeaders) { } - - /// - public new IWebApiResponse Copy() => - new WebApiResponse(this.Content, this.StatusCode, this.CacheState, this.ResponseHeaders); } /// @@ -100,9 +96,5 @@ public WebApiResponse(T content, HttpStatusCode? statusCode, CacheState cacheSta /// public IDictionary ResponseHeaders { get; } = new Dictionary(); - - /// - public IWebApiResponse Copy() => - new WebApiResponse(this.Content, this.StatusCode, this.CacheState, this.ResponseHeaders); } } diff --git a/Gw2Sharp/WebApi/Middleware/ExceptionMiddleware.cs b/Gw2Sharp/WebApi/Middleware/ExceptionMiddleware.cs index fb28ce7cb..528fdb25e 100644 --- a/Gw2Sharp/WebApi/Middleware/ExceptionMiddleware.cs +++ b/Gw2Sharp/WebApi/Middleware/ExceptionMiddleware.cs @@ -70,7 +70,7 @@ async Task ExecAsync() #endif HttpStatusCode.InternalServerError => new ServerErrorException(context.Request, errorResponse), HttpStatusCode.ServiceUnavailable => new ServiceUnavailableException(context.Request, errorResponse), - _ => new UnexpectedStatusException(context.Request, httpResponse, httpResponse.Content) + _ => new UnexpectedStatusException(context.Request, errorResponse) }; } }