Skip to content

Commit

Permalink
Fix Discord bot not handling http error responses properly when runni…
Browse files Browse the repository at this point in the history
…ng on modern dotnet versions
  • Loading branch information
UnknownShadow200 committed Mar 29, 2024
1 parent 82ac48d commit 3445209
Showing 1 changed file with 36 additions and 32 deletions.
68 changes: 36 additions & 32 deletions MCGalaxy/Modules/Relay/Discord/DiscordApiClient.cs
Expand Up @@ -70,40 +70,10 @@ public sealed class DiscordApiClient : AsyncWorker<DiscordApiMessage>
msg.ProcessResponse(resp);
break;
} catch (WebException ex) {
string err = HttpUtil.GetErrorResponse(ex);
bool canRetry = HandleErrorResponse(ex, msg, retry);
HttpUtil.DisposeErrorResponse(ex);
HttpStatusCode status = GetStatus(ex);

// 429 errors simply require retrying after sleeping for a bit
if (status == (HttpStatusCode)429) {
SleepForRetryPeriod(ex.Response);
continue;
}

// 500 errors might be temporary Discord outage, so still retry a few times
if (status >= (HttpStatusCode)500 && status <= (HttpStatusCode)504) {
LogWarning(ex);
LogResponse(err);
if (retry >= 2) return;
continue;
}

// If unable to reach Discord at all, immediately give up
if (ex.Status == WebExceptionStatus.NameResolutionFailure) {
LogWarning(ex);
return;
}

// May be caused by connection dropout/reset, so still retry a few times
if (ex.InnerException is IOException) {
LogWarning(ex);
if (retry >= 2) return;
continue;
}

LogError(ex, msg);
LogResponse(err);
return;
if (!canRetry) return;
} catch (Exception ex) {
LogError(ex, msg);
return;
Expand All @@ -115,6 +85,40 @@ public sealed class DiscordApiClient : AsyncWorker<DiscordApiMessage>
if (remaining == "1") SleepForRetryPeriod(res);
}

static bool HandleErrorResponse(WebException ex, DiscordApiMessage msg, int retry) {
string err = HttpUtil.GetErrorResponse(ex);
HttpStatusCode status = GetStatus(ex);

// 429 errors simply require retrying after sleeping for a bit
if (status == (HttpStatusCode)429) {
SleepForRetryPeriod(ex.Response);
return true;
}

// 500 errors might be temporary Discord outage, so still retry a few times
if (status >= (HttpStatusCode)500 && status <= (HttpStatusCode)504) {
LogWarning(ex);
LogResponse(err);
return retry < 2;
}

// If unable to reach Discord at all, immediately give up
if (ex.Status == WebExceptionStatus.NameResolutionFailure) {
LogWarning(ex);
return false;
}

// May be caused by connection dropout/reset, so still retry a few times
if (ex.InnerException is IOException) {
LogWarning(ex);
return retry < 2;
}

LogError(ex, msg);
LogResponse(err);
return false;
}


static HttpStatusCode GetStatus(WebException ex) {
if (ex.Response == null) return 0;
Expand Down

0 comments on commit 3445209

Please sign in to comment.