Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redo of PR 378 #407

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions TwitchLib.Api.Core/HttpCallHandlers/TwitchErrorResponse.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
35 changes: 19 additions & 16 deletions TwitchLib.Api.Core/HttpCallHandlers/TwitchHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

/// <summary>
Expand Down Expand Up @@ -94,7 +95,7 @@ public async Task<KeyValuePair<int, string>> GeneralRequestAsync(string url, str
return new KeyValuePair<int, string>((int)response.StatusCode, respStr);
}

HandleWebException(response);
await HandleWebException(response);
return new KeyValuePair<int, string>(0, null);
}

Expand All @@ -120,34 +121,36 @@ public async Task<int> 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<TwitchErrorResponse>(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}");
}
}

}
}
}
Loading