diff --git a/TwitchLib.Api.Core/HttpCallHandlers/TwitchErrorResponse.cs b/TwitchLib.Api.Core/HttpCallHandlers/TwitchErrorResponse.cs new file mode 100644 index 00000000..ebab57df --- /dev/null +++ b/TwitchLib.Api.Core/HttpCallHandlers/TwitchErrorResponse.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace TwitchLib.Api.Core.HttpCallHandlers +{ + public class TwitchErrorResponse + { + [JsonProperty("error")] + public string Error; + + [JsonProperty("status")] + public int Status; + + [JsonProperty("message")] + public string Message; + } +} diff --git a/TwitchLib.Api.Core/HttpCallHandlers/TwitchHttpClient.cs b/TwitchLib.Api.Core/HttpCallHandlers/TwitchHttpClient.cs index 0e713e75..c53f79ae 100644 --- a/TwitchLib.Api.Core/HttpCallHandlers/TwitchHttpClient.cs +++ b/TwitchLib.Api.Core/HttpCallHandlers/TwitchHttpClient.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Newtonsoft.Json; using TwitchLib.Api.Core.Common; using TwitchLib.Api.Core.Enums; using TwitchLib.Api.Core.Exceptions; @@ -43,7 +44,7 @@ public async Task PutBytesAsync(string url, byte[] payload) var response = await _http.PutAsync(new Uri(url), new ByteArrayContent(payload)).ConfigureAwait(false); if (!response.IsSuccessStatusCode) - HandleWebException(response); + await HandleWebException(response); } /// @@ -94,7 +95,7 @@ public async Task> GeneralRequestAsync(string url, str return new KeyValuePair((int)response.StatusCode, respStr); } - HandleWebException(response); + await HandleWebException(response); return new KeyValuePair(0, null); } @@ -120,34 +121,36 @@ public async Task RequestReturnResponseCodeAsync(string url, string method, return (int)response.StatusCode; } - private void HandleWebException(HttpResponseMessage errorResp) + private async Task HandleWebException(HttpResponseMessage errorResp) { + var bodyContent = await errorResp.Content.ReadAsStringAsync(); + var deserializedError = JsonConvert.DeserializeObject(bodyContent); + switch (errorResp.StatusCode) { case HttpStatusCode.BadRequest: - throw new BadRequestException("Your request failed because either: \n 1. Your ClientID was invalid/not set. \n 2. Your refresh token was invalid. \n 3. You requested a username when the server was expecting a user ID.", errorResp); + throw new BadRequestException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); case HttpStatusCode.Unauthorized: var authenticateHeader = errorResp.Headers.WwwAuthenticate; if (authenticateHeader == null || authenticateHeader.Count <= 0) - throw new BadScopeException("Your request was blocked due to bad credentials (Do you have the right scope for your access token?).", errorResp); - throw new TokenExpiredException("Your request was blocked due to an expired Token. Please refresh your token and update your API instance settings.", errorResp); + throw new BadScopeException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); + throw new TokenExpiredException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); case HttpStatusCode.NotFound: - throw new BadResourceException("The resource you tried to access was not valid.", errorResp); + throw new BadResourceException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); case (HttpStatusCode)429: - errorResp.Headers.TryGetValues("Ratelimit-Reset", out var resetTime); - throw new TooManyRequestsException("You have reached your rate limit. Too many requests were made", resetTime.FirstOrDefault(), errorResp); + errorResp.Headers.TryGetValues($"Ratelimit-Reset", out var resetTime); + throw new TooManyRequestsException($"{deserializedError.Error} - {deserializedError.Message}", resetTime.FirstOrDefault(), errorResp); case HttpStatusCode.BadGateway: - throw new BadGatewayException("The API answered with a 502 Bad Gateway. Please retry your request", errorResp); + throw new BadGatewayException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); case HttpStatusCode.GatewayTimeout: - throw new GatewayTimeoutException("The API answered with a 504 Gateway Timeout. Please retry your request", errorResp); + throw new GatewayTimeoutException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); case HttpStatusCode.InternalServerError: - throw new InternalServerErrorException("The API answered with a 500 Internal Server Error. Please retry your request", errorResp); + throw new InternalServerErrorException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); case HttpStatusCode.Forbidden: - throw new BadTokenException("The token provided in the request did not match the associated user. Make sure the token you're using is from the resource owner (streamer? viewer?)", errorResp); + throw new BadTokenException($"{deserializedError.Error} - {deserializedError.Message}", errorResp); default: - throw new HttpRequestException("Something went wrong during the request! Please try again later"); + throw new HttpRequestException($"{deserializedError.Error} - {deserializedError.Message}"); } } - } -} \ No newline at end of file +}