From e5cb3366678bf0512532a17a0a74ce4e9a4078c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=84=AD=E6=B2=9B=E8=BB=92?= Date: Wed, 17 Sep 2025 00:44:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=A6=E4=BD=9C=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E9=8C=AF=E8=AA=A4=E6=97=A5=E8=AA=8C=E7=B3=BB=E7=B5=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 ErrorHandlingMiddleware 全域錯誤處理 - 升級日誌配置到 Debug 層級 - 添加詳細的認證流程日誌 - 改進 AuthController 錯誤處理 - 包含請求詳情和錯誤堆疊追蹤 - 支援結構化日誌記錄 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../Controllers/AuthController.cs | 30 ++++++++- .../Middleware/ErrorHandlingMiddleware.cs | 66 +++++++++++++++++++ backend/DramaLing.Api/Program.cs | 5 ++ backend/DramaLing.Api/appsettings.json | 15 ++++- 4 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 backend/DramaLing.Api/Middleware/ErrorHandlingMiddleware.cs diff --git a/backend/DramaLing.Api/Controllers/AuthController.cs b/backend/DramaLing.Api/Controllers/AuthController.cs index 408120a..b106234 100644 --- a/backend/DramaLing.Api/Controllers/AuthController.cs +++ b/backend/DramaLing.Api/Controllers/AuthController.cs @@ -35,9 +35,17 @@ public class AuthController : ControllerBase { try { + _logger.LogInformation("Registration attempt for user: {Username}, Email: {Email}", + request.Username, request.Email); + // 驗證請求 if (!ModelState.IsValid) + { + _logger.LogWarning("Invalid model state for registration: {@ModelErrors}", + ModelState.Where(x => x.Value?.Errors.Count > 0) + .ToDictionary(x => x.Key, x => x.Value?.Errors.Select(e => e.ErrorMessage))); return BadRequest(new { Success = false, Error = "Invalid request data" }); + } // 檢查Email是否已存在 if (await _context.Users.AnyAsync(u => u.Email == request.Email)) @@ -90,11 +98,17 @@ public class AuthController : ControllerBase } catch (Exception ex) { - _logger.LogError(ex, "Error during user registration"); + _logger.LogError(ex, "Error during user registration. Request: {@Request}", new { + Username = request.Username, + Email = request.Email, + StackTrace = ex.StackTrace, + InnerException = ex.InnerException?.Message + }); return StatusCode(500, new { Success = false, Error = "Registration failed", + Details = ex.Message, Timestamp = DateTime.UtcNow }); } @@ -105,9 +119,16 @@ public class AuthController : ControllerBase { try { + _logger.LogInformation("Login attempt for email: {Email}", request.Email); + // 驗證請求 if (!ModelState.IsValid) + { + _logger.LogWarning("Invalid model state for login: {@ModelErrors}", + ModelState.Where(x => x.Value?.Errors.Count > 0) + .ToDictionary(x => x.Key, x => x.Value?.Errors.Select(e => e.ErrorMessage))); return BadRequest(new { Success = false, Error = "Invalid request data" }); + } // 查找用戶 var user = await _context.Users.FirstOrDefaultAsync(u => u.Email == request.Email); @@ -143,11 +164,16 @@ public class AuthController : ControllerBase } catch (Exception ex) { - _logger.LogError(ex, "Error during user login"); + _logger.LogError(ex, "Error during user login. Request: {@Request}", new { + Email = request.Email, + StackTrace = ex.StackTrace, + InnerException = ex.InnerException?.Message + }); return StatusCode(500, new { Success = false, Error = "Login failed", + Details = ex.Message, Timestamp = DateTime.UtcNow }); } diff --git a/backend/DramaLing.Api/Middleware/ErrorHandlingMiddleware.cs b/backend/DramaLing.Api/Middleware/ErrorHandlingMiddleware.cs new file mode 100644 index 0000000..df11b20 --- /dev/null +++ b/backend/DramaLing.Api/Middleware/ErrorHandlingMiddleware.cs @@ -0,0 +1,66 @@ +using System.Net; +using System.Text.Json; + +namespace DramaLing.Api.Middleware; + +public class ErrorHandlingMiddleware +{ + private readonly RequestDelegate _next; + private readonly ILogger _logger; + + public ErrorHandlingMiddleware(RequestDelegate next, ILogger logger) + { + _next = next; + _logger = logger; + } + + public async Task InvokeAsync(HttpContext context) + { + try + { + await _next(context); + } + catch (Exception ex) + { + _logger.LogError(ex, "An unhandled exception occurred during request execution. Request: {Method} {Path}", + context.Request.Method, context.Request.Path); + + await HandleExceptionAsync(context, ex); + } + } + + private async Task HandleExceptionAsync(HttpContext context, Exception exception) + { + context.Response.ContentType = "application/json"; + + var errorResponse = new + { + Success = false, + Error = "An error occurred while processing your request", + Details = exception.Message, + Timestamp = DateTime.UtcNow, + RequestId = context.TraceIdentifier + }; + + var statusCode = exception switch + { + ArgumentException => HttpStatusCode.BadRequest, + UnauthorizedAccessException => HttpStatusCode.Unauthorized, + KeyNotFoundException => HttpStatusCode.NotFound, + NotImplementedException => HttpStatusCode.NotImplemented, + TimeoutException => HttpStatusCode.RequestTimeout, + _ => HttpStatusCode.InternalServerError + }; + + context.Response.StatusCode = (int)statusCode; + + var jsonResponse = JsonSerializer.Serialize(errorResponse, new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }); + + _logger.LogError("Error response sent: {StatusCode} - {Response}", statusCode, jsonResponse); + + await context.Response.WriteAsync(jsonResponse); + } +} \ No newline at end of file diff --git a/backend/DramaLing.Api/Program.cs b/backend/DramaLing.Api/Program.cs index 2c6cd59..8d72942 100644 --- a/backend/DramaLing.Api/Program.cs +++ b/backend/DramaLing.Api/Program.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using DramaLing.Api.Data; using DramaLing.Api.Services; +using DramaLing.Api.Middleware; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; @@ -111,6 +112,10 @@ builder.Services.AddSwaggerGen(c => var app = builder.Build(); // Configure the HTTP request pipeline. + +// 全域錯誤處理中介軟體 (必須放在最前面) +app.UseMiddleware(); + if (app.Environment.IsDevelopment()) { app.UseSwagger(); diff --git a/backend/DramaLing.Api/appsettings.json b/backend/DramaLing.Api/appsettings.json index 6e3f327..184196b 100644 --- a/backend/DramaLing.Api/appsettings.json +++ b/backend/DramaLing.Api/appsettings.json @@ -1,9 +1,18 @@ { "Logging": { "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning", - "Microsoft.EntityFrameworkCore": "Warning" + "Default": "Debug", + "Microsoft.AspNetCore": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "DramaLing.Api": "Debug", + "System": "Information", + "Microsoft": "Information" + }, + "Console": { + "IncludeScopes": true, + "LogLevel": { + "Default": "Debug" + } } }, "AllowedHosts": "*",