简体   繁体   English

处理.net中的异常

[英]handling exceptions in .net

I have asked a few questions on here and read a few articles around exception handling but don't think I'm really grasping when you should and when you shouldn't handle an exception. 我在这里问了几个问题并阅读了一些关于异常处理的文章,但是我不认为我应该在你应该什么时候以及什么时候不应该处理异常。 From the articles I've read it states to "only handle exceptions you can recover from" What does it mean by that. 从我读过的文章中可以看出“只处理你可以从中恢复的异常”这是什么意思。 If I can't handle the exception what do I do? 如果我无法处理异常,我该怎么办? Let it propagate back up the stack? 让它传播回堆栈? If I don't handle it how can I log it and present a user friendly error message. 如果我不处理它,我如何记录它并提供用户友好的错误消息。 What do most people do in web apps and web services? 大多数人在网络应用和网络服务方面做了什么?

As an example say I have a lower tier data layer that pulls data from sql 举个例子说我有一个从sql中提取数据的低层数据层

try{
  //do something with db
}catch(SqlException ex){
 //what should i do here
 //should i call code again to retry getting data from db
}catch(Exception ex){
 //should i even catch exception of type exception
}

How do I handle exceptions in lower tiers? 如何处理较低层中的异常? Should I just let the exception bubble up the tiers? 我应该让异常泡到层级吗? If so then if I want to catch an exception of type sqlexception then I need a reference to the library sqlexception is part of but surely I shouldn't have to reference that library in a layer that has nothing to do with data access. 如果是这样,那么如果我想捕获sqlexception类型的异常,那么我需要对库sqlexception的引用是一部分,但我当然不应该在与数据访问无关的层中引用该库。

Some simple ground rules: 一些简单的基本规则:

  • Handling an exception requires that the state of your program is exactly the same as it was before the code got started that caused the exception. 处理异常需要程序的状态与导致异常的代码启动前的状态完全相同 You will need lots of catch and finally blocks that restore variables back to their initial state. 您需要大量的catch和finally块才能将变量恢复到初始状态。

  • Only consider handling an exception if catching it allows the program to continue running in a meaningful way. 只有在捕获它时才考虑处理异常允许程序以有意义的方式继续运行。 Hard to do anything useful when the database server is off line for example, might as well stop the program. 例如,当数据库服务器脱机时很难做任何有用的事情,也可以停止程序。

  • If you need a human to take corrective action (you almost always do) then be sure that she has enough information to troubleshoot the problem. 如果您需要一个人来采取纠正措施(您几乎总是这样做),那么请确保她有足够的信息来解决问题。 Let exceptions bubble up to the UI layer. 让异常冒泡到UI层。 Avoid interpreting exceptions (no "Could not update the database" for example), display the exact exception message and stack trace. 避免解释异常(例如,“无法更新数据库”),显示确切的异常消息和堆栈跟踪。

  • Implement a handler for AppDomain.CurrentDomain.UnhandledException and log or display the value of e.ExceptionObject. 为AppDomain.CurrentDomain.UnhandledException实现一个处理程序,并记录或显示e.ExceptionObject的值。 Helps to diagnose unhandled exceptions. 帮助诊断未处理的异常。 And helps you avoid putting catch everywhere. 并帮助您避免在任何地方放置捕获物

  • A hundred unhandled exceptions with a good diagnostic is better than one caught one that destabilizes the program so it generates bad data or causes other unrelated exceptions to be thrown. 具有良好诊断的一百个未处理异常优于一个破坏程序稳定性的异常,因此它会生成错误数据或导致其他无关异常被抛出。

Okay, this will be far too brief since it's still early in the morning here but i've been struggling with this same question so here is what I understand: 好吧,这将是太短暂的,因为它仍然在清晨,但我一直在努力解决这个问题,所以这就是我的理解:

"only handle exceptions you can recover from" “只处理你可以从中恢复的异常”

My understanding here is that you get the exception to a level in your code where you can do something about it. 我的理解是,您可以在代码中获得一个级别的异常,您可以在其中执行某些操作。 In the case of your low level code, you would let the exception bubble back up into a layer where you could modify your 'process' to handle the exception and possibly try the process again. 对于低级代码,您可以将异常气泡备份到一个层,您可以在其中修改“进程”以处理异常并可能再次尝试该过程。 (I typically log the error right where it is thrown.) (我通常会在错误的位置记录错误。)

Exception management is a large subject, so I'll only touch the surface here. 异常管理是一个很大的主题,所以我只会触及表面。

From the articles ive read it states to "only handle exceptions you can recover from" What does it mean by that. 从我读过的文章中可以看出“只处理你可以从中恢复的异常”这是什么意思。

If you don't know how to recover from a specific exception, then there's not usually any point in catching it. 如果您不知道如何从特定异常中恢复,那么捕获它通常没有任何意义。 If it's a web app or service, the web server itself will deal with the logging and recovery. 如果它是Web应用程序或服务,Web服务器本身将处理日志记录和恢复。

In some cases, you need to catch exceptions so that you can a generic recovery, for example by cancelling or reversing a transaction. 在某些情况下,您需要捕获异常,以便可以进行常规恢复,例如通过取消或撤消事务。 In that case, an acceptable approach is to 在这种情况下,可接受的方法是
catch the exception, do the generic recovery, and then throw the exception again. 捕获异常,执行泛型恢复,然后再次抛出异常。

If i cant handle the exception what do i do. 如果我无法处理异常,我该怎么办。 Let it propgate back up the stack? 让它支持堆栈?

Yes. 是。

If i dont handle it how can i log it and present a user friendly error message. 如果我不处理它我如何记录它并提供用户友好的错误消息。 What do most people do in web apps and web services? 大多数人在网络应用和网络服务方面做了什么?

The web server will log the exception. Web服务器将记录异常。 If you want to present a user-friendly error message in a web app, you can catch/log at the highest level of the stack and re-direct to your error message. 如果要在Web应用程序中显示用户友好的错误消息,可以捕获/记录堆栈的最高级别并重定向到您的错误消息。 Again, I would try not to catch System.Exception - instead make a list of the exceptions that your app throws, and catch just these types before presenting a message tailored to each type. 同样,我会尝试不捕获System.Exception - 而是列出应用程序抛出的异常列表,并在呈现针对每种类型定制的消息之前捕获这些类型。 As the list of exception types grows, either prevent each new exception type by changing the code, or add a new catch for that exception type. 随着异常类型列表的增长,要么通过更改代码来阻止每个新的异常类型,要么为该异常类型添加新的catch。

In a web service, you can create a custom exception and add that as a node to the generic exception that the web service will provide. 在Web服务中,您可以创建自定义异常并将其作为节点添加到Web服务将提供的常规异常中。

In your code example, I wouldn't use try...catch unless you're expecting an exception and you know what to do with it. 在你的代码示例中,我不会使用try ... catch,除非你期待一个异常并且你知道如何处理它。

How do i handle exceptions in lower tiers. 如何处理较低层中的异常。 Should i just let the exception bubble up the tiers. 我应该让异常泡沫层级。

Yes. 是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM