From 7e02e86cd6089feebd8f0d2653fb5c432aa778eb Mon Sep 17 00:00:00 2001 From: Toutsu Date: Mon, 25 May 2026 12:46:56 +0300 Subject: [PATCH] fix: add Discord OAuth token exchange logging for production diagnostics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Log status code and response body when Discord /oauth2/token fails - Helps identify why ExchangeCodeAsync returns null in production Bump version → 2.8.1 Co-Authored-By: Claude Opus 4.7 --- .gitea/workflows/deploy.yml | 2 +- Directory.Build.props | 2 +- compose.yaml | 2 +- src/GmRelay.Web/Components/Layout/NavMenu.razor | 2 +- src/GmRelay.Web/Services/DiscordAuthService.cs | 12 ++++++++---- .../GmRelay.Bot.Tests/Web/DiscordAuthServiceTests.cs | 9 +++++---- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 5440737..0cf95a2 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -6,7 +6,7 @@ on: - main env: - VERSION: 2.8.0 + VERSION: 2.8.1 jobs: # ЧАСТЬ 1: Собираем образы и кладем в Gitea (чтобы делиться с ребятами) diff --git a/Directory.Build.props b/Directory.Build.props index 3cc296b..400b286 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 2.8.0 + 2.8.1 net10.0 preview enable diff --git a/compose.yaml b/compose.yaml index 2bdbd1a..bef964d 100644 --- a/compose.yaml +++ b/compose.yaml @@ -49,7 +49,7 @@ services: crond -f bot: - image: git.codeanddice.ru/toutsu/gmrelay-bot:2.8.0 + image: git.codeanddice.ru/toutsu/gmrelay-bot:2.8.1 restart: always depends_on: db: diff --git a/src/GmRelay.Web/Components/Layout/NavMenu.razor b/src/GmRelay.Web/Components/Layout/NavMenu.razor index 745eff7..70ad5ad 100644 --- a/src/GmRelay.Web/Components/Layout/NavMenu.razor +++ b/src/GmRelay.Web/Components/Layout/NavMenu.razor @@ -66,7 +66,7 @@ - + diff --git a/src/GmRelay.Web/Services/DiscordAuthService.cs b/src/GmRelay.Web/Services/DiscordAuthService.cs index 6733c2c..485d878 100644 --- a/src/GmRelay.Web/Services/DiscordAuthService.cs +++ b/src/GmRelay.Web/Services/DiscordAuthService.cs @@ -5,7 +5,7 @@ using System.Text.Json.Serialization; namespace GmRelay.Web.Services; -public sealed class DiscordAuthService(IHttpClientFactory httpClientFactory, IConfiguration configuration) +public sealed class DiscordAuthService(IHttpClientFactory httpClientFactory, IConfiguration configuration, ILogger logger) { private readonly DiscordOAuthOptions _options = configuration.GetSection("Discord").Get() ?? new DiscordOAuthOptions(); @@ -40,10 +40,14 @@ public sealed class DiscordAuthService(IHttpClientFactory httpClientFactory, ICo }); var response = await client.PostAsync("https://discord.com/api/oauth2/token", content); - if (!response.IsSuccessStatusCode) - return null; - var json = await response.Content.ReadAsStringAsync(); + if (!response.IsSuccessStatusCode) + { + logger.LogError("Discord token exchange failed: {StatusCode} {Body}. client_id={ClientId}, redirect_uri={RedirectUri}", + (int)response.StatusCode, json, _options.ClientId, _options.RedirectUri); + return null; + } + return JsonSerializer.Deserialize(json); } diff --git a/tests/GmRelay.Bot.Tests/Web/DiscordAuthServiceTests.cs b/tests/GmRelay.Bot.Tests/Web/DiscordAuthServiceTests.cs index 8e27711..710dc21 100644 --- a/tests/GmRelay.Bot.Tests/Web/DiscordAuthServiceTests.cs +++ b/tests/GmRelay.Bot.Tests/Web/DiscordAuthServiceTests.cs @@ -3,6 +3,7 @@ using System.Text.Json; using GmRelay.Web; using GmRelay.Web.Services; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging.Abstractions; namespace GmRelay.Bot.Tests.Web; @@ -20,7 +21,7 @@ public class DiscordAuthServiceTests }) .Build(); - var service = new DiscordAuthService(new TestHttpClientFactory(), config); + var service = new DiscordAuthService(new TestHttpClientFactory(), config, NullLogger.Instance); var url = service.BuildAuthorizeUrl("state123"); Assert.Contains("client_id=12345", url); @@ -33,7 +34,7 @@ public class DiscordAuthServiceTests public void BuildAuthorizeUrl_WithMissingConfig_ThrowsInvalidOperationException() { var config = new ConfigurationBuilder().Build(); - var service = new DiscordAuthService(new TestHttpClientFactory(), config); + var service = new DiscordAuthService(new TestHttpClientFactory(), config, NullLogger.Instance); Assert.Throws(() => service.BuildAuthorizeUrl("state")); } @@ -74,7 +75,7 @@ public class DiscordAuthServiceTests .Build(); var factory = new TestHttpClientFactory(handler); - var service = new DiscordAuthService(factory, config); + var service = new DiscordAuthService(factory, config, NullLogger.Instance); var result = await service.ExchangeCodeAsync("valid_code"); @@ -102,7 +103,7 @@ public class DiscordAuthServiceTests .Build(); var factory = new TestHttpClientFactory(handler); - var service = new DiscordAuthService(factory, config); + var service = new DiscordAuthService(factory, config, NullLogger.Instance); var result = await service.ExchangeCodeAsync("invalid_code");