From 1e49d8f789b354b43458e9ca31df031a7f82467c Mon Sep 17 00:00:00 2001 From: David Young Date: Sun, 17 May 2026 11:36:35 +1200 Subject: [PATCH] fix(api): log test-connection failures with provider context The /api/test-usenet-connection endpoint silently caught both CouldNotConnectToUsenetException and CouldNotLoginToUsenetException and returned `connected: false` with no logging. Users seeing "Connection test failed" in the UI had no way to diagnose the underlying cause (bad credentials, DNS failure, TLS handshake failure, server-side rejection, unreachable host, etc.). Add Serilog warnings to each catch block, including host, port, SSL flag, user, and the inner exception message. The connect and login paths log distinct prefixes ("connect error" / "login error") so operators can quickly tell which step failed. Also catch unexpected non-cancellation exceptions, log with stack trace, then rethrow so BaseApiController's existing 500 handler still runs and the frontend continues to receive its current error shape for non-NNTP failures. Co-Authored-By: Claude Opus 4.7 --- .../TestUsenetConnectionController.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/backend/Api/Controllers/TestUsenetConnection/TestUsenetConnectionController.cs b/backend/Api/Controllers/TestUsenetConnection/TestUsenetConnectionController.cs index 63684a39..7fe319a0 100644 --- a/backend/Api/Controllers/TestUsenetConnection/TestUsenetConnectionController.cs +++ b/backend/Api/Controllers/TestUsenetConnection/TestUsenetConnectionController.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Mvc; using NzbWebDAV.Clients.Usenet; using NzbWebDAV.Exceptions; +using NzbWebDAV.Extensions; +using Serilog; namespace NzbWebDAV.Api.Controllers.TestUsenetConnection; @@ -15,14 +17,26 @@ private async Task TestUsenetConnection(TestUsenet await UsenetStreamingClient.CreateNewConnection(request.ToConnectionDetails(), HttpContext.RequestAborted).ConfigureAwait(false); return new TestUsenetConnectionResponse { Status = true, Connected = true }; } - catch (CouldNotConnectToUsenetException) + catch (CouldNotConnectToUsenetException e) { + var inner = e.InnerException?.Message ?? e.Message; + Log.Warning("Test connection failed for {Host}:{Port} (ssl={UseSsl}, user={User}): connect error: {Error}", + request.Host, request.Port, request.UseSsl, request.User, inner); return new TestUsenetConnectionResponse { Status = true, Connected = false }; } - catch (CouldNotLoginToUsenetException) + catch (CouldNotLoginToUsenetException e) { + var inner = e.InnerException?.Message ?? e.Message; + Log.Warning("Test connection failed for {Host}:{Port} (ssl={UseSsl}, user={User}): login error: {Error}", + request.Host, request.Port, request.UseSsl, request.User, inner); return new TestUsenetConnectionResponse { Status = true, Connected = false }; } + catch (Exception e) when (!e.IsCancellationException()) + { + Log.Warning(e, "Test connection failed for {Host}:{Port} (ssl={UseSsl}, user={User}): unexpected error", + request.Host, request.Port, request.UseSsl, request.User); + throw; + } } protected override async Task HandleRequest()