diff --git a/marketplace/Empostor.Plugins.DiscordWebhook.dll b/marketplace/Empostor.Plugins.DiscordWebhook.dll index 0e4aa20..5f1fdb3 100644 Binary files a/marketplace/Empostor.Plugins.DiscordWebhook.dll and b/marketplace/Empostor.Plugins.DiscordWebhook.dll differ diff --git a/src/Empostor.Plugins.DiscordWebhook/DiscordWebhookListener.cs b/src/Empostor.Plugins.DiscordWebhook/DiscordWebhookListener.cs index 2971dce..0203061 100644 --- a/src/Empostor.Plugins.DiscordWebhook/DiscordWebhookListener.cs +++ b/src/Empostor.Plugins.DiscordWebhook/DiscordWebhookListener.cs @@ -345,19 +345,40 @@ public sealed class DiscordWebhookListener : IEventListener TrimUrl(url) + (url.Contains('?') ? "&" : "?") + "wait=true", new StringContent(json, Encoding.UTF8, "application/json")); + // Read the body regardless of status so failures carry diagnostic content + // (proxies, captive portals and WAFs answer with arbitrary non-JSON text). + var body = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) { - _logger.LogWarning("DiscordWebhook live message create returned {Status}", (int)response.StatusCode); + _logger.LogWarning( + "DiscordWebhook live message create returned {Status}: {Body}", + (int)response.StatusCode, Truncate(body)); return null; } - var body = await response.Content.ReadAsStringAsync(); - using var doc = JsonDocument.Parse(body); - return doc.RootElement.TryGetProperty("id", out var id) && id.ValueKind == JsonValueKind.String - ? id.GetString() - : null; + try + { + using var doc = JsonDocument.Parse(body); + return doc.RootElement.TryGetProperty("id", out var id) && id.ValueKind == JsonValueKind.String + ? id.GetString() + : null; + } + catch (JsonException ex) + { + // A 2xx response that is not JSON did not come from Discord. Logging the body + // makes the culprit (proxy, hijacked DNS, wrong URL) immediately visible. + _logger.LogError( + ex, + "DiscordWebhook live message create returned non-JSON body ({Bytes} bytes): {Body}", + body.Length, Truncate(body)); + return null; + } } + private static string Truncate(string s) + => s.Length <= 300 ? s : s.Substring(0, 300) + "…"; + /// Returns true when the message no longer exists (404). private async ValueTask PatchLiveMessageAsync(TrackedLobby lobby, object embed) {