如何从共享库类方法将异常信息传递至Web API?
解决异常从AddStockTransfer传递到Web API Create方法的问题
我来帮你搞定这个异常传递的事儿!目前你的代码里AddStockTransfer方法捕获异常后只记录了日志,但没有把异常信息传递给上层的Create方法——因为你把异常“吞”了,Create的try块根本感知不到错误发生。下面给你两种可行的解决方案:
方案一:重新抛出异常(推荐,适合需要中断流程的场景)
修改AddStockTransfer方法,在记录日志后重新抛出异常,这样Create方法就能捕获到完整的错误信息:
修改后的AddStockTransfer方法
public void AddStockTransfer(StockTransfer item) { using (var connection = new SqlConnection(ConfigurationManager.AppSettings["DataConnectionLive"])) { connection.Open(); string insertQuery = @" INSERT INTO[fuel].[StockTransfer] ([StockTransferGuid] ,[StockItemId] ,[Quantity] ,[SourceWarehouseId] ,[SourceBin] ,[TargetWarehouseId] ,[TargetBin] ,[DateTimeCreated] ,[DateTimeLastUpdated] ,[StockTransferStatus] ,[StatusMessage]) VALUES (@StockTransferGuid,@StockItemId,@Quantity,@SourceWarehouseId,@SourceBin,@TargetWarehouseId,@TargetBin,@DateTimeCreated,@DateTimeLastUpdated,@StockTransferStatus,@StatusMessage)"; var mydate = DateTime.Now; var mydate2 = DateTime.Now; var result = connection.Execute(insertQuery, new { item.StockTransferGuid, item.StockItemId, item.Quantity, item.SourceWarehouseId, item.SourceBin, item.TargetWarehouseId, item.TargetBin, mydate, mydate2, item.StockTransferStatus, item.StatusMessage }); } catch (Exception ex) { logger.Warn("Connection string is " + connection.ConnectionString.ToString()); logger.Warn("Error occurred on add stock transfer function " + ex.Message.ToString()); // 重新抛出异常,包装成更明确的业务异常,同时保留原始异常堆栈 throw new InvalidOperationException("添加库存转移记录失败", ex); // 如果想保留原始异常类型,直接写 throw; 即可 } }
修改后的Create方法
[HttpPost] public ActionResult Create(StockTransfer stockTrans) { try { database.AddStockTransfer(stockTrans); // 返回明确的成功响应 return Json(new { success = true, message = "库存转移记录添加成功" }); } catch (Exception ex) { // 这里能拿到AddStockTransfer传递过来的异常详情 logger.Warn($"Error on Create: {ex.Message}", ex); // 生产环境建议返回友好提示,不要暴露原始异常细节;开发环境可以返回详细信息方便调试 var errorMsg = ex.InnerException != null ? ex.InnerException.Message : ex.Message; return Json(new { success = false, message = $"添加失败:{errorMsg}" }); } }
方案二:用返回值传递结果(适合不需要中断流程的场景)
如果不想抛出异常,可以定义一个结果类,让AddStockTransfer返回操作状态和错误信息:
定义操作结果类
public class OperationResult { public bool Success { get; set; } public string ErrorMessage { get; set; } public Exception InnerException { get; set; } }
修改后的AddStockTransfer方法
public OperationResult AddStockTransfer(StockTransfer item) { try { using (var connection = new SqlConnection(ConfigurationManager.AppSettings["DataConnectionLive"])) { connection.Open(); string insertQuery = @" INSERT INTO[fuel].[StockTransfer] ([StockTransferGuid] ,[StockItemId] ,[Quantity] ,[SourceWarehouseId] ,[SourceBin] ,[TargetWarehouseId] ,[TargetBin] ,[DateTimeCreated] ,[DateTimeLastUpdated] ,[StockTransferStatus] ,[StatusMessage]) VALUES (@StockTransferGuid,@StockItemId,@Quantity,@SourceWarehouseId,@SourceBin,@TargetWarehouseId,@TargetBin,@DateTimeCreated,@DateTimeLastUpdated,@StockTransferStatus,@StatusMessage)"; var mydate = DateTime.Now; var mydate2 = DateTime.Now; var result = connection.Execute(insertQuery, new { item.StockTransferGuid, item.StockItemId, item.Quantity, item.SourceWarehouseId, item.SourceBin, item.TargetWarehouseId, item.TargetBin, mydate, mydate2, item.StockTransferStatus, item.StatusMessage }); } return new OperationResult { Success = true }; } catch (Exception ex) { logger.Warn("Connection string is " + connection.ConnectionString.ToString()); logger.Warn("Error occurred on add stock transfer function " + ex.Message.ToString()); return new OperationResult { Success = false, ErrorMessage = ex.Message, InnerException = ex }; } }
修改后的Create方法
[HttpPost] public ActionResult Create(StockTransfer stockTrans) { var operationResult = database.AddStockTransfer(stockTrans); if (!operationResult.Success) { logger.Warn($"Error on Create: {operationResult.ErrorMessage}", operationResult.InnerException); return Json(new { success = false, message = "添加失败,请联系管理员" }); } return Json(new { success = true, message = "库存转移记录添加成功" }); }
关键注意点
- 不要吞异常:原始代码中
AddStockTransfer的catch块只记录日志不抛出,导致上层完全不知道错误发生,这是常见的错误。 - 保留异常上下文:用
throw new ...(message, ex)可以把原始异常作为InnerException传递,保留完整的错误堆栈,方便排查问题。 - 生产环境安全:不要把数据库连接字符串、原始异常堆栈等敏感信息返回给前端,只返回用户友好的提示信息,详细错误记录在日志里即可。
内容的提问来源于stack exchange,提问作者dotnetdevcsharp
相关产品推荐
相关产品推荐

