From beb86fa0fec95798ecc3811a93efad3b6675ef93 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 20 Aug 2024 14:12:30 -0700 Subject: [PATCH] Add failure logging to DiscordWebhook.cs (#30835) * Add failure logging to DiscordWebhook.cs Add a new function that logs errors with discord webhook's http requests. Create, Delete, and Edit functions were modified slightly to call the log function but return the same information as before. The log function logs the error code, caller method using a simple constant (could be better), and attempts to log headers mentioned in issue #30248. * remove extra ';' Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Move header error logs to debug --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: Pieter-Jan Briers --- Content.Server/Discord/DiscordWebhook.cs | 43 ++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/Content.Server/Discord/DiscordWebhook.cs b/Content.Server/Discord/DiscordWebhook.cs index ace5766764..878cd5975a 100644 --- a/Content.Server/Discord/DiscordWebhook.cs +++ b/Content.Server/Discord/DiscordWebhook.cs @@ -68,7 +68,11 @@ public sealed class DiscordWebhook : IPostInjectInit public async Task CreateMessage(WebhookIdentifier identifier, WebhookPayload payload) { var url = $"{GetUrl(identifier)}?wait=true"; - return await _http.PostAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + var response = await _http.PostAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + + LogResponse(response, "Create"); + + return response; } /// @@ -80,7 +84,11 @@ public sealed class DiscordWebhook : IPostInjectInit public async Task DeleteMessage(WebhookIdentifier identifier, ulong messageId) { var url = $"{GetUrl(identifier)}/messages/{messageId}"; - return await _http.DeleteAsync(url); + var response = await _http.DeleteAsync(url); + + LogResponse(response, "Delete"); + + return response; } /// @@ -93,11 +101,40 @@ public sealed class DiscordWebhook : IPostInjectInit public async Task EditMessage(WebhookIdentifier identifier, ulong messageId, WebhookPayload payload) { var url = $"{GetUrl(identifier)}/messages/{messageId}"; - return await _http.PatchAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + var response = await _http.PatchAsJsonAsync(url, payload, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + + LogResponse(response, "Edit"); + + return response; } void IPostInjectInit.PostInject() { _sawmill = _log.GetSawmill("DISCORD"); } + + /// + /// Logs detailed information about the HTTP response received from a Discord webhook request. + /// If the response status code is non-2XX it logs the status code, relevant rate limit headers. + /// + /// The HTTP response received from the Discord API. + /// The name (constant) of the method that initiated the webhook request (e.g., "Create", "Edit", "Delete"). + private void LogResponse(HttpResponseMessage response, string methodName) + { + if (!response.IsSuccessStatusCode) + { + _sawmill.Error($"Failed to {methodName} message. Status code: {response.StatusCode}."); + + if (response.Headers.TryGetValues("Retry-After", out var retryAfter)) + _sawmill.Debug($"Failed webhook response Retry-After: {string.Join(", ", retryAfter)}"); + + if (response.Headers.TryGetValues("X-RateLimit-Global", out var globalRateLimit)) + _sawmill.Debug($"Failed webhook response X-RateLimit-Global: {string.Join(", ", globalRateLimit)}"); + + if (response.Headers.TryGetValues("X-RateLimit-Scope", out var rateLimitScope)) + _sawmill.Debug($"Failed webhook response X-RateLimit-Scope: {string.Join(", ", rateLimitScope)}"); + } + } + + } -- 2.51.2