P0 实现全局异常处理中间件:移除所有Controller重复try-catch,统一异常响应
This commit is contained in:
parent
949fa8e85b
commit
89244fc078
@ -51,8 +51,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>创建的投资组合信息</returns>
|
/// <returns>创建的投资组合信息</returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public ActionResult<ApiResponse<CreatePortfolioResponse>> CreatePortfolio([FromBody] CreatePortfolioRequest request)
|
public ActionResult<ApiResponse<CreatePortfolioResponse>> CreatePortfolio([FromBody] CreatePortfolioRequest request)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -123,18 +121,6 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "success"
|
message = "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error creating portfolio");
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<CreatePortfolioResponse>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = null,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前用户的投资组合列表
|
/// 获取当前用户的投资组合列表
|
||||||
@ -142,8 +128,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>投资组合列表</returns>
|
/// <returns>投资组合列表</returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public ActionResult<ApiResponse<GetPortfoliosResponse>> GetPortfolios()
|
public ActionResult<ApiResponse<GetPortfoliosResponse>> GetPortfolios()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -169,18 +153,6 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "success"
|
message = "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error retrieving portfolios");
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<GetPortfoliosResponse>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = null,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前用户的总资产概览
|
/// 获取当前用户的总资产概览
|
||||||
@ -188,8 +160,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>总资产数据(总市值、今日盈亏、累计收益率等)</returns>
|
/// <returns>总资产数据(总市值、今日盈亏、累计收益率等)</returns>
|
||||||
[HttpGet("assets")]
|
[HttpGet("assets")]
|
||||||
public ActionResult<ApiResponse<TotalAssetsResponse>> GetTotalAssets()
|
public ActionResult<ApiResponse<TotalAssetsResponse>> GetTotalAssets()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -215,18 +185,6 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "success"
|
message = "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error retrieving total assets");
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<TotalAssetsResponse>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = null,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取单个投资组合详情
|
/// 获取单个投资组合详情
|
||||||
@ -235,8 +193,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>投资组合详情(含持仓明细)</returns>
|
/// <returns>投资组合详情(含持仓明细)</returns>
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public async Task<ActionResult<ApiResponse<PortfolioDetailResponse>>> GetPortfolioById(string id)
|
public async Task<ActionResult<ApiResponse<PortfolioDetailResponse>>> GetPortfolioById(string id)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -262,18 +218,6 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "success"
|
message = "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error retrieving portfolio");
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<PortfolioDetailResponse>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = null,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取投资组合的交易记录(流水)
|
/// 获取投资组合的交易记录(流水)
|
||||||
@ -284,8 +228,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>交易记录列表</returns>
|
/// <returns>交易记录列表</returns>
|
||||||
[HttpGet("transactions")]
|
[HttpGet("transactions")]
|
||||||
public ActionResult<ApiResponse<GetTransactionsResponse>> GetTransactions([FromQuery] string portfolioId, [FromQuery] int limit = 10, [FromQuery] int offset = 0)
|
public ActionResult<ApiResponse<GetTransactionsResponse>> GetTransactions([FromQuery] string portfolioId, [FromQuery] int limit = 10, [FromQuery] int offset = 0)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -311,18 +253,6 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "success"
|
message = "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error retrieving transactions");
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<GetTransactionsResponse>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = null,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 记录一笔交易(买入/卖出)
|
/// 记录一笔交易(买入/卖出)
|
||||||
@ -331,8 +261,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>创建的交易记录</returns>
|
/// <returns>创建的交易记录</returns>
|
||||||
[HttpPost("transactions")]
|
[HttpPost("transactions")]
|
||||||
public ActionResult<ApiResponse<CreateTransactionResponse>> CreateTransaction([FromBody] CreateTransactionRequest request)
|
public ActionResult<ApiResponse<CreateTransactionResponse>> CreateTransaction([FromBody] CreateTransactionRequest request)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -405,18 +333,6 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "success"
|
message = "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error creating transaction");
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<CreateTransactionResponse>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = null,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取投资组合策略信号
|
/// 获取投资组合策略信号
|
||||||
@ -425,8 +341,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>策略信号</returns>
|
/// <returns>策略信号</returns>
|
||||||
[HttpGet("{id}/signal")]
|
[HttpGet("{id}/signal")]
|
||||||
public async Task<ActionResult<ApiResponse<StrategySignal>>> GetPortfolioSignal(string id)
|
public async Task<ActionResult<ApiResponse<StrategySignal>>> GetPortfolioSignal(string id)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -489,18 +403,6 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "success"
|
message = "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error getting portfolio signal: {PortfolioId}", id);
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategySignal>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = null,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除投资组合
|
/// 删除投资组合
|
||||||
@ -509,8 +411,6 @@ public class PortfolioController : ControllerBase
|
|||||||
/// <returns>删除结果</returns>
|
/// <returns>删除结果</returns>
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public async Task<ActionResult<ApiResponse<bool>>> DeletePortfolio(string id)
|
public async Task<ActionResult<ApiResponse<bool>>> DeletePortfolio(string id)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (string.IsNullOrEmpty(userId))
|
if (string.IsNullOrEmpty(userId))
|
||||||
@ -579,16 +479,4 @@ public class PortfolioController : ControllerBase
|
|||||||
message = "删除成功"
|
message = "删除成功"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error deleting portfolio");
|
|
||||||
|
|
||||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<bool>
|
|
||||||
{
|
|
||||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
|
||||||
data = false,
|
|
||||||
message = ex.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
80
AssetManager.API/Middleware/GlobalExceptionMiddleware.cs
Normal file
80
AssetManager.API/Middleware/GlobalExceptionMiddleware.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using AssetManager.Models;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AssetManager.API.Middleware;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 全局异常处理中间件:统一捕获所有API异常,返回标准格式响应
|
||||||
|
/// </summary>
|
||||||
|
public class GlobalExceptionMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly ILogger<GlobalExceptionMiddleware> _logger;
|
||||||
|
|
||||||
|
public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger)
|
||||||
|
{
|
||||||
|
_next = next;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "请求处理异常: {Path}", context.Request.Path);
|
||||||
|
await HandleExceptionAsync(context, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
|
||||||
|
{
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
var response = new ApiResponse<object>
|
||||||
|
{
|
||||||
|
code = StatusCodes.Status500InternalServerError,
|
||||||
|
data = null,
|
||||||
|
message = exception.Message
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据异常类型设置不同的状态码
|
||||||
|
switch (exception)
|
||||||
|
{
|
||||||
|
case UnauthorizedAccessException _:
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||||
|
response.code = StatusCodes.Status401Unauthorized;
|
||||||
|
response.message = "未授权访问";
|
||||||
|
break;
|
||||||
|
case ArgumentException _:
|
||||||
|
case InvalidOperationException _:
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
response.code = StatusCodes.Status400BadRequest;
|
||||||
|
break;
|
||||||
|
case KeyNotFoundException _:
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
response.code = StatusCodes.Status404NotFound;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
|
response.code = StatusCodes.Status500InternalServerError;
|
||||||
|
// 生产环境可以隐藏具体错误信息,避免泄露敏感信息
|
||||||
|
// response.message = "服务器内部错误";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = JsonSerializer.Serialize(response, new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||||
|
});
|
||||||
|
|
||||||
|
return context.Response.WriteAsync(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -115,6 +115,9 @@ var app = builder.Build();
|
|||||||
// 初始化数据库
|
// 初始化数据库
|
||||||
app.Services.InitializeDatabase();
|
app.Services.InitializeDatabase();
|
||||||
|
|
||||||
|
// 全局异常处理中间件(必须放在最前面)
|
||||||
|
app.UseMiddleware<GlobalExceptionMiddleware>();
|
||||||
|
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user