From cf163123947c773d6be4ce5ae0873c6fafca72ce Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 11 Jun 2026 13:33:15 +0200 Subject: [PATCH] Refactor error handling in DocumentService and consumers Refactored `DocumentService.GetDocumentAsync` to throw `HttpRequestException` on failure instead of returning a tuple. Updated all consumers to handle exceptions, improving error handling consistency across the application. Enhanced error messages for better user feedback and added logging for improved traceability. Updated `EnvelopeReceiverPage`, `EnvelopeReceiverPage_DxReportViewer`, and `ReportViewer` to use the new exception-based API and handle errors gracefully. This change simplifies the API, improves maintainability, and makes the application more robust and user-friendly. --- .../Pages/EnvelopeReceiverPage.razor | 8 ++++++-- .../EnvelopeReceiverPage_DxReportViewer.razor | 14 +++++++++----- .../Pages/Example/ReportViewer.razor | 11 ++++++++--- .../Services/DocumentService.cs | 16 ++++++++++++---- 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage.razor b/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage.razor index 1d033c2f..4f303d57 100644 --- a/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage.razor +++ b/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage.razor @@ -563,13 +563,13 @@ const int MaxThumbnailWidth = 400; } try { - var (pdfBytes, statusCode) = await DocumentService.GetDocumentAsync(EnvelopeKey); + var pdfBytes = await DocumentService.GetDocumentAsync(EnvelopeKey); if (pdfBytes is { Length: > 0 }) { var base64 = Convert.ToBase64String(pdfBytes); _pdfDataUrl = $"data:application/pdf;base64,{base64}"; } else { - _errorMessage = $"Dokument konnte nicht geladen werden. HTTP Status: {statusCode}"; + _errorMessage = "Dokument konnte nicht geladen werden: Keine Daten empfangen."; } var signatures = await SignatureService.GetAsync(EnvelopeKey); @@ -608,8 +608,12 @@ const int MaxThumbnailWidth = 400; _popupValidationMessage = null; } + } catch (HttpRequestException ex) { + _errorMessage = $"Dokument konnte nicht geladen werden: {ex.Message}"; + logger.LogError(ex, "Failed to load document for envelope {EnvelopeKey}", EnvelopeKey); } catch (Exception ex) { _errorMessage = $"Fehler: {ex.Message}"; + logger.LogError(ex, "Unexpected error during initialization for envelope {EnvelopeKey}", EnvelopeKey); } _isLoading = false; diff --git a/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage_DxReportViewer.razor b/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage_DxReportViewer.razor index 4c00c09d..3a84ea71 100644 --- a/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage_DxReportViewer.razor +++ b/EnvelopeGenerator.ReceiverUI/Pages/EnvelopeReceiverPage_DxReportViewer.razor @@ -25,11 +25,15 @@ protected override async Task OnInitializedAsync() { if (!AppOptions.Value.UsePredefinedReports) { - var (pdfBytes, _) = await DocumentService.GetDocumentAsync(EnvelopeKey); - if (pdfBytes is { Length: > 0 }) - BasePdfBytes = pdfBytes; - else - throw new InvalidOperationException($"No PDF bytes found for EnvelopeKey: {EnvelopeKey}"); + try { + var pdfBytes = await DocumentService.GetDocumentAsync(EnvelopeKey); + if (pdfBytes is { Length: > 0 }) + BasePdfBytes = pdfBytes; + else + throw new InvalidOperationException($"No PDF bytes found for EnvelopeKey: {EnvelopeKey}"); + } catch (HttpRequestException ex) { + throw new InvalidOperationException($"Failed to load document for EnvelopeKey: {EnvelopeKey}", ex); + } } Report = CreateReport(); diff --git a/EnvelopeGenerator.ReceiverUI/Pages/Example/ReportViewer.razor b/EnvelopeGenerator.ReceiverUI/Pages/Example/ReportViewer.razor index e7a1ea45..8fc8eca3 100644 --- a/EnvelopeGenerator.ReceiverUI/Pages/Example/ReportViewer.razor +++ b/EnvelopeGenerator.ReceiverUI/Pages/Example/ReportViewer.razor @@ -346,9 +346,14 @@ Shown="OnPopupShownAsync"> _envelopeReceiver = await EnvelopeReceiverService.GetAsync(EnvelopeKey ?? "fake"); if (!AppOptions.Value.UsePredefinedReports && !string.IsNullOrWhiteSpace(EnvelopeKey)) { - var (pdfBytes, _) = await DocumentService.GetDocumentAsync(EnvelopeKey); - if (pdfBytes is { Length: > 0 }) - _basePdfBytes = pdfBytes; + try { + var pdfBytes = await DocumentService.GetDocumentAsync(EnvelopeKey); + if (pdfBytes is { Length: > 0 }) + _basePdfBytes = pdfBytes; + } catch (HttpRequestException ex) { + // Log error but continue - will use predefined report instead + Console.WriteLine($"Failed to load document: {ex.Message}"); + } } var initialReport = BuildFreshBaseReport(); diff --git a/EnvelopeGenerator.ReceiverUI/Services/DocumentService.cs b/EnvelopeGenerator.ReceiverUI/Services/DocumentService.cs index 57d44bfb..08363893 100644 --- a/EnvelopeGenerator.ReceiverUI/Services/DocumentService.cs +++ b/EnvelopeGenerator.ReceiverUI/Services/DocumentService.cs @@ -11,17 +11,25 @@ public class DocumentService(HttpClient http, IOptions apiOptions) /// /// Fetches the PDF bytes for the given envelope key from the API. - /// Returns null bytes with the HTTP status code on failure. + /// Throws HttpRequestException on failure with appropriate status code. /// - public async Task<(byte[]? Bytes, HttpStatusCode StatusCode)> GetDocumentAsync(string envelopeKey, CancellationToken cancel = default) + /// Thrown when the API request fails. + public async Task GetDocumentAsync(string envelopeKey, CancellationToken cancel = default) { var response = await http.GetAsync($"{_api.BaseUrl}/api/Document/{Uri.EscapeDataString(envelopeKey)}", cancel); if (!response.IsSuccessStatusCode) - return (null, response.StatusCode); + { + var statusCode = (int)response.StatusCode; + var reasonPhrase = response.ReasonPhrase ?? "Unknown error"; + throw new HttpRequestException( + $"Failed to load document. Status: {statusCode} ({reasonPhrase})", + null, + response.StatusCode); + } var bytes = await response.Content.ReadAsByteArrayAsync(cancel); - return (bytes, response.StatusCode); + return bytes; } }