[英]try/catch vs AppDomain.UnhandledException to log & crash the application
As far as I know, you are supposed to only use try/catch when you will actually handle the exception and not just report&log it and then crash the application. 据我所知,您应该仅在实际处理异常时才使用try / catch,而不仅仅是报告和记录异常,然后使应用程序崩溃。 Otherwise, you are better off just checking different scenarios where it makes sense (eg if sth==null) or - if your purpose is just to log the exception and crash the application - to use AppDomain.UnhandledException . 否则,最好只检查有意义的其他方案(例如,如果sth == null),或者-如果您的目的只是记录异常并使应用程序崩溃,则最好使用AppDomain.UnhandledException 。 But is this always the case and why? 但是,情况总是如此吗?为什么?
Suppose the following method, which accepts an array and returns MemoryStream after doing some database and filesystem operations. 假设以下方法接受一个数组,并在执行一些数据库和文件系统操作后返回MemoryStream。
MemoryStream Read (int[] IDs)
{
try
{
using (SqlConnection connection = new SqlConnection(connection_string))
{
connection.Open();
// a bunch of code executing SQL queries & constructing MemoryStream, which is returned at the end of the block
}
}
catch (Exception e)
{
// report the exception to the user & log it
throw; // pointles??
}
}
There are multiple situations that can be considered exceptional/unwanted behavior, such as: 有多种情况可以视为异常/不必要的行为,例如:
All these cases are considered exceptional, still putting everything inside a try/catch if you only want to log an exception (then crash) is probably bad practice - but why? 所有这些情况都被认为是例外情况,如果您只想记录一个异常(然后崩溃),那么仍然将所有内容放入try / catch中可能是不好的做法-但是为什么呢? What would be the best handling behavior in the above case? 在上述情况下最佳的处理行为是什么? Avoid try/catch completely, check null references using an if statement (return null in such case) and use AppDomain.UnhandledException to log everything else? 避免完全尝试/捕获,使用if语句检查空引用(在这种情况下返回null),并使用AppDomain.UnhandledException记录其他所有内容? Use try/catch, but still check for null references inside using if statements (and return in that case)? 使用try / catch,但仍使用if语句检查内部是否为空引用(在这种情况下返回)? Something else? 还有吗
Peppering your code with try/catch statements only to crash the app isn't productive. 用try / catch语句添加代码只会使应用程序崩溃不会提高生产力。 The CLR already takes care of that for you. CLR已经为您解决了这一问题。 And you've got AppDomain.UnhandledException to generate decent information to diagnose the cause. 并且您已经有了AppDomain.UnhandledException来生成体面的信息来诊断原因。
Only in the very specific case that you have to clean up something, say a file that you don't want to keep laying about, should you consider writing a try/catch. 仅在非常特殊的情况下,您必须清理某些内容,例如不想保留的文件,才考虑编写try / catch。 Which in itself is a very iffy requirement, there is no guarantee whatsoever that your catch block will execute. 这本身是一个非常棘手的要求,无法保证您的catch块将执行。 It will not when the exception is nasty like StackOverflowException or ExecutionEngineException. 如果异常讨厌,例如StackOverflowException或ExecutionEngineException,则不会。 Or the more common reason that programs don't clean up after themselves, somebody tripping over the power cord or killing the process from Task Manager. 或更常见的原因是程序无法自行清理,有人在电源线上绊倒或杀死了任务管理器中的进程。
you are supposed to only use try/catch when you will actually handle the exception and not just report & log it and then crash the application 您应该仅在实际处理异常时才使用try / catch,而不仅仅是报告和记录异常,然后使应用程序崩溃
I agree with the first part, although I would add that adding logging at the tier boundaries is valuable when you may not have control over the calling tier. 我同意第一部分,尽管我会补充说,当您可能无法控制调用层时,在层边界添加日志记录很有价值。 eg I log all exceptions that occur in a Web Service at the top method to ensure I have logging on the server since debug info (stack trace, etc) does not always cross comm layers gracefully 例如,由于调试信息(堆栈跟踪等)并不总是优雅地跨越通讯层,因此我以最上面的方法记录了Web服务中发生的所有异常,以确保我已登录服务器
In your particular example I would check for "exceptional" conditions where you can but let other exception occur "naturally". 在您的特定示例中,我将检查“例外”条件,在该条件下您可以让其他例外“自然”发生。 For your specific examples: 对于您的特定示例:
- argument (IDs[]) being null, 参数(IDs [])为null,
- failure to establish an SQL connection, 无法建立SQL连接,
- failure to execute a specific SQL query. 无法执行特定的SQL查询。
For the first one, I would check for null
arguments for one reason: A NullReferenceException
gives you no context about the cause of the exception, other that where it occurs. 对于第一个,我会检查null
的参数为一个原因:一个NullReferenceException
让你没有关于异常的原因,其他的是它所出现的上下文。 I much prefer to check for null
and then throw a new ArgumentNullException
exception since you can add which argument is null. 我更喜欢检查null
,然后引发新的ArgumentNullException
异常,因为您可以添加哪个参数为null。 You may still need to do some digging to find out why it's null but it saves you a lot of time in debugging. 您可能仍需要进行一些挖掘,以找出为什么它为null的原因 ,但这可以节省大量的调试时间。
SQL Exceptions can typically bubble up naturally, since they have decent error information in them (eg "undeclared variable '@arg'"
) SQL异常通常会自然冒泡,因为它们中包含不错的错误信息(例如"undeclared variable '@arg'"
)
I've recently began reading up on this topic myself. 我最近开始自己阅读有关此主题的内容。 My basic understanding is: 我的基本理解是:
It's important to note that "handling" an exception doesn't necessarily mean clean up or retroactive logic. 重要的是要注意,“处理”异常并不一定意味着清除或追溯逻辑。 Handling could simply mean formatting an error to something more user-friendly or to hide a sensitive stack trace you wouldn't want just anyone to see. 处理可能只是意味着将错误格式化为更用户友好的格式,或者隐藏了您不希望任何人看到的敏感堆栈跟踪。 I routinely log a detailed error and return a formatted one. 我通常记录一个详细的错误,并返回一个格式化的错误。
Again, this is just what I've gathered initially. 同样,这就是我最初收集的内容。 Below are some sources: 以下是一些来源:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.