From 6acc92ca27f48f3102603588a4ab14abfe28fda7 Mon Sep 17 00:00:00 2001 From: luoqian <2769838458@qq.com> Date: Fri, 22 May 2026 15:17:59 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=A9=BA=20catch=20?= =?UTF-8?q?=E5=90=9E=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98=EF=BC=8C=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E5=8F=B7=E6=8A=BD=E7=A6=BB=E5=88=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=EF=BC=8C=E7=BB=9F=E4=B8=80=E6=97=A5=E5=BF=97=E4=B8=BA=20Serilo?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 所有空 catch 块补全日志记录,统一使用 Serilog/AppLog - 按场景分级:Error(意外失败)、Warning(次要问题)、Information(预期内) - 端口 HttpPort/HttpsPort 抽离到 appsettings.json Server 配置节 - QrCodeService 通过 IConfiguration 读取端口,消除硬编码 - 前端通过 Vite proxy 转发 /api,http.ts 统一使用 origin 地址 - 移除所有 Debug.WriteLine 和 Serilog.Log.Debug 日志 Co-Authored-By: Claude Opus 4.7 --- FileShare-API/Program.cs | 6 ++++-- FileShare-API/appsettings.json | 4 ++++ FileShare-EFCore/Database/DatabaseManager.cs | 3 ++- FileShare-PC/Views/MainWindow.axaml.cs | 18 +++++++++++++----- FileShare-Services/Endpoints/AppEndpoints.cs | 4 ++-- .../Extensions/DesktopEndpointAdapter.cs | 1 + .../Services/FileLibrary/FileLibraryService.cs | 10 ++++++---- .../Services/QrCode/QrCodeService.cs | 6 ++++-- FileShare-Web-VUE/src/api/http.ts | 7 ++----- FileShare-Web-VUE/vite.config.ts | 6 ++++++ 10 files changed, 44 insertions(+), 21 deletions(-) diff --git a/FileShare-API/Program.cs b/FileShare-API/Program.cs index 29c814f..96f4423 100644 --- a/FileShare-API/Program.cs +++ b/FileShare-API/Program.cs @@ -13,8 +13,10 @@ try { var builder = WebApplication.CreateBuilder(args); - // 配置 Kestrel 监听所有本机 IP - builder.WebHost.UseUrls("http://0.0.0.0:5206", "https://0.0.0.0:7165"); + // 配置 Kestrel 监听所有本机 IP(端口从 Server 配置节读取) + var httpPort = builder.Configuration.GetValue("Server:HttpPort", 5206); + var httpsPort = builder.Configuration.GetValue("Server:HttpsPort", 7165); + builder.WebHost.UseUrls($"http://0.0.0.0:{httpPort}", $"https://0.0.0.0:{httpsPort}"); // 使用 Serilog 作为日志提供程序 builder.Host.UseSerilog(); diff --git a/FileShare-API/appsettings.json b/FileShare-API/appsettings.json index 67f2b44..b4d641c 100644 --- a/FileShare-API/appsettings.json +++ b/FileShare-API/appsettings.json @@ -6,6 +6,10 @@ } }, "AllowedHosts": "*", + "Server": { + "HttpPort": 5206, + "HttpsPort": 7165 + }, "Jwt": { "Issuer": "FileShare-API", "Audience": "FileShare-Client", diff --git a/FileShare-EFCore/Database/DatabaseManager.cs b/FileShare-EFCore/Database/DatabaseManager.cs index 47d978e..59a7963 100644 --- a/FileShare-EFCore/Database/DatabaseManager.cs +++ b/FileShare-EFCore/Database/DatabaseManager.cs @@ -95,8 +95,9 @@ namespace FileShare_EFCore.Database { return await _context.Database.CanConnectAsync(); } - catch + catch (Exception ex) { + AppLog.Warning("数据库连接测试失败 Provider={Provider} Error={Error}", _config.Provider, ex.Message); return false; } } diff --git a/FileShare-PC/Views/MainWindow.axaml.cs b/FileShare-PC/Views/MainWindow.axaml.cs index 895d573..2e8e205 100644 --- a/FileShare-PC/Views/MainWindow.axaml.cs +++ b/FileShare-PC/Views/MainWindow.axaml.cs @@ -1,4 +1,5 @@ using Avalonia.Controls; +using FileShare_Common.Infrastructure; using System; using System.Collections.Generic; using System.IO; @@ -180,6 +181,7 @@ namespace FileShare_PC.Views } catch (Exception ex) { + AppLog.Error(ex, "Bridge AppRequest 处理失败"); response = new AppResponse { Kind = "app-response", @@ -341,6 +343,7 @@ namespace FileShare_PC.Views } catch (Exception ex) { + AppLog.Error(ex, "本地 HTTP 请求处理失败"); response.StatusCode = 500; response.StatusMessage = "Internal Server Error"; response.Body = JsonSerializer.Serialize(new { success = false, error = ex.Message }); @@ -456,8 +459,9 @@ namespace FileShare_PC.Views using var document = JsonDocument.Parse(messageJson); return document.RootElement.TryGetProperty("id", out var idProperty) ? idProperty.GetString() : null; } - catch + catch (Exception ex) { + AppLog.Information("解析 Bridge 请求 ID 失败: {Error}", ex.Message); return null; } } @@ -537,8 +541,9 @@ namespace FileShare_PC.Views _ = Task.Run(() => HandleLocalHttpRequest(context, wwwRoot), cancellationToken); } } - catch + catch (Exception ex) when (ex is not OperationCanceledException) { + AppLog.Error(ex, "本地 HTTP 服务循环异常退出"); } } @@ -577,15 +582,17 @@ namespace FileShare_PC.Views await input.CopyToAsync(context.Response.OutputStream); context.Response.OutputStream.Close(); } - catch + catch (Exception ex) { + AppLog.Error(ex, "本地静态文件请求处理失败"); try { context.Response.StatusCode = 500; context.Response.Close(); } - catch + catch (Exception closeEx) { + AppLog.Warning("关闭 500 响应失败: {Error}", closeEx.Message); } } } @@ -826,8 +833,9 @@ namespace FileShare_PC.Views _localHttpServer?.Stop(); _localHttpServer?.Close(); } - catch + catch (Exception ex) { + AppLog.Warning("停止本地 HTTP 服务时出错: {Error}", ex.Message); } finally { diff --git a/FileShare-Services/Endpoints/AppEndpoints.cs b/FileShare-Services/Endpoints/AppEndpoints.cs index 4080f4b..c0a007c 100644 --- a/FileShare-Services/Endpoints/AppEndpoints.cs +++ b/FileShare-Services/Endpoints/AppEndpoints.cs @@ -26,9 +26,9 @@ namespace FileShare_Services.Endpoints // ---- 全局日志过滤器(记录每个请求) ---- endpoints.AddGlobalFilter(async (ctx, next) => { - Serilog.Log.Debug("→ {Method} {Path}", ctx.Method, ctx.Path); + Serilog.Log.Information("→ {Method} {Path}", ctx.Method, ctx.Path); await next(ctx); - Serilog.Log.Debug("← {Method} {Path} | {StatusCode}", ctx.Method, ctx.Path, ctx.StatusCode); + Serilog.Log.Information("← {Method} {Path} | {StatusCode}", ctx.Method, ctx.Path, ctx.StatusCode); }); // ---- 业务端点注册 ---- diff --git a/FileShare-Services/Extensions/DesktopEndpointAdapter.cs b/FileShare-Services/Extensions/DesktopEndpointAdapter.cs index 6f4b3e6..2e593a1 100644 --- a/FileShare-Services/Extensions/DesktopEndpointAdapter.cs +++ b/FileShare-Services/Extensions/DesktopEndpointAdapter.cs @@ -190,6 +190,7 @@ namespace FileShare_Services.Extensions } catch (Exception ex) { + Serilog.Log.Error(ex, "桌面端点处理异常 | {Method} {Path}", method, path); ctx.StatusCode = 500; ctx.StatusMessage = "Internal Server Error"; ctx.ResponseBody = new { success = false, error = ex.Message }; diff --git a/FileShare-Services/Services/FileLibrary/FileLibraryService.cs b/FileShare-Services/Services/FileLibrary/FileLibraryService.cs index 8481baf..d2c227c 100644 --- a/FileShare-Services/Services/FileLibrary/FileLibraryService.cs +++ b/FileShare-Services/Services/FileLibrary/FileLibraryService.cs @@ -223,9 +223,9 @@ namespace FileShare_Services.Services.FileLibrary { await ScanRootAsync(root.Id, cancellationToken); } - catch + catch (Exception ex) { - // ScanRootAsync records the error on the root. Continue scanning other roots. + Serilog.Log.Warning(ex, "扫描文件库根目录失败 RootId={RootId}", root.Id); } } } @@ -378,8 +378,9 @@ namespace FileShare_Services.Services.FileLibrary directories = Directory.EnumerateDirectories(current); files = Directory.EnumerateFiles(current); } - catch + catch (Exception ex) { + Serilog.Log.Information(ex, "无法枚举目录 {Directory},已跳过", current); continue; } @@ -460,8 +461,9 @@ namespace FileShare_Services.Services.FileLibrary { return drive.IsReady ? selector(drive) : null; } - catch + catch (Exception ex) { + Serilog.Log.Information(ex, "获取驱动器属性失败,已跳过"); return null; } } diff --git a/FileShare-Services/Services/QrCode/QrCodeService.cs b/FileShare-Services/Services/QrCode/QrCodeService.cs index c103cb2..f05115c 100644 --- a/FileShare-Services/Services/QrCode/QrCodeService.cs +++ b/FileShare-Services/Services/QrCode/QrCodeService.cs @@ -1,5 +1,6 @@ using FileShare_Common.Core; using FileShare_Services.Core; +using Microsoft.Extensions.Configuration; using QRCoder; using System.Net; using System.Net.NetworkInformation; @@ -10,7 +11,7 @@ namespace FileShare_Services.Services.QrCode /// /// 二维码生成服务,获取局域网 IP 并生成 PNG 格式的访问二维码。 /// - public sealed class QrCodeService : IQrCodeService + public sealed class QrCodeService(IConfiguration configuration) : IQrCodeService { /// public Task GenerateQrCodeAsync(ServiceEndpointContext ctx) @@ -19,7 +20,8 @@ namespace FileShare_Services.Services.QrCode if (ip is null) throw new InvalidOperationException("无法获取局域网IP地址"); - var url = $"http://{ip}:5206"; + var port = int.TryParse(configuration["Server:HttpPort"], out var p) ? p : 5206; + var url = $"http://{ip}:{port}"; var base64 = GeneratePngBase64(url); return Task.FromResult(ResponseHelper.Ok(new QrCodeResponse(url, base64))); } diff --git a/FileShare-Web-VUE/src/api/http.ts b/FileShare-Web-VUE/src/api/http.ts index fb8c038..4975399 100644 --- a/FileShare-Web-VUE/src/api/http.ts +++ b/FileShare-Web-VUE/src/api/http.ts @@ -4,11 +4,8 @@ import { isWebView2 } from './env' // WebView2 自定义协议前缀 const WEBVIEW2_BASE = 'app://api/' -// Vite 开发页走 5206 API;API 托管前端时使用同源地址。 -const isViteDevServer = window.location.port === '51552' -const HTTP_ORIGIN = isViteDevServer - ? `${window.location.protocol}//${window.location.hostname || 'localhost'}:5206` - : window.location.origin +// Vite 开发时通过 proxy 转发 /api 到后端;API 托管前端时使用同源地址。 +const HTTP_ORIGIN = window.location.origin const HTTP_BASE = `${HTTP_ORIGIN}/api/` export const apiOrigin = (): string => HTTP_ORIGIN diff --git a/FileShare-Web-VUE/vite.config.ts b/FileShare-Web-VUE/vite.config.ts index 496f438..09dc539 100644 --- a/FileShare-Web-VUE/vite.config.ts +++ b/FileShare-Web-VUE/vite.config.ts @@ -10,5 +10,11 @@ export default defineConfig({ }, server: { port: 51552, + proxy: { + '/api': { + target: 'http://localhost:5206', + changeOrigin: true, + }, + }, }, })