我在我的应用程序中遵循这种处理异常的方式。但我的领导说我做错了。我只是简单地包装并重新抛出相同的异常,这将影响性能。
我的做法有什么问题?有没有人对如何在此处记录和处理异常有任何建议?
public class BusinessRepository : IBusinessRepo
{
public List<Employee> GetEmployees()
{
try
{
//do some DB operations
}
catch (SQLException sqlex)
{
Logger.Log("Exception detail with full stack trace");
throw new DALException(sqlex, "Error in data access layer");
}
}
}
public class BusinessLayerClass : IBusinessLayer
{
private readonly IBusinessRepo Repo;
public BusinessLayerClass(IBusinessRepo rep)
{
Repo = rep;
}
public List<Employee> GetEmployees()
{
try
{
List<Employee> emps= return Repo.GetEmployees();
}
catch (DALException dex)
{
//do nothin as it got already logged
throw;
}
catch (Exception ex)
{
Logger.Log(ex, "Business layer ex");
throw new BusinessLayerEx(ex);
}
}
}
public class HomeController : Controller
{
public ActionResult Index()
{
try
{
List < Employee >= BusinessLayerClass.GetEmployees();
}
catch (DALException)
{
//show error msg to user
}
catch (BusinessLayerEx)
{
//show error msg to user
}
catch (Exception ex)
{
Logger.Log();
//show error msg to user
}
return View(emps);
}
}
我是否遵循上面显示的正确的冒泡,处理和记录方式?
答案 0 :(得分:3)
只要满足两个条件,我倾向于同意你这样做的方式:
Logger.Log
语句记录的内容比您在此处指出的内容更有意义/有用(我猜这里的代码只是一条示例消息,表明记录了错误)。如果它提供了可用于追踪异常原因的信息,那就好了。//show error msg to user
评论意味着在该位置,您会呈现一个很好的视图,说明发生了错误,并且您不只是显示默认的异常屏幕/ strack跟踪。至于你的throw;
,当你抓住DALException时,你刚刚扔了:没关系。你的目标似乎是捕获前一层出来的任何异常并记录它,然后抛出你自己的异常。因为只有在你已经记录了另一个错误并且自己抛出它之后才会抛出DALException,所以让它在这个级别上冒出来是完全没问题的。
答案 1 :(得分:1)
例外的一般经验法则是不要抓住它们,除非你能“对它做些什么”,即增加价值。理想情况下,这将是某种优雅的恢复,用户永远不会知道有打嗝,但至少这将包括记录异常 - 你正在做的。
不要抓住异常只是为了立即重新抛出它。这没有任何价值。 (例外情况可能是,如果您需要将异常类型更改为更具信息性/适合上下文的内容)。
答案 2 :(得分:1)
与任何正常的返回机制相比,抛出和捕获异常是昂贵的,但它除了重点之外 - 我们不应该使用异常作为正常的控制流机制,而是处理异常的事情。
在技术上,异常处理可能非常具有挑战性。毕竟,大多数时候我们完全不指望它们。但是,如果团队或项目根本没有任何策略来进行错误处理,那么几乎不可能让异常处理“正确”的是什么。在一个理想的世界中,我们一开始就知道我们需要应对什么样的错误条件,并且我们将整个应用程序设计为考虑到这些(以及我们还需要记住的大量其他约束,从代码可读性到性能)。
我会说如果你的主管说“这是错的”,那么问“我们的错误处理策略是什么?”是公平的。如果你甚至不知道你的代码应该达到什么目的,你怎么可能提供优秀的代码呢?