如何使用 try catch 进行异常处理是最佳实践 [英] How using try catch for exception handling is best practice
问题描述
在维护我同事的代码时,即使是自称是高级开发人员的人,我也经常看到以下代码:
while maintaining my colleague's code from even someone who claims to be a senior developer, I often see the following code:
try
{
//do something
}
catch
{
//Do nothing
}
或者有时他们将日志信息写入日志文件,如以下 try catch
块
or sometimes they write logging information to log files like following try catch
block
try
{
//do some work
}
catch(Exception exception)
{
WriteException2LogFile(exception);
}
我只是想知道他们所做的是否是最佳实践?这让我很困惑,因为在我看来,用户应该知道系统会发生什么.
I am just wondering if what they have done is the best practice? It makes me confused because in my thinking users should know what happens with the system.
推荐答案
我的异常处理策略是:
通过挂钩到
Application.ThreadException 事件
来捕获所有未处理的异常,然后决定:
- 对于 UI 应用程序:向用户显示道歉消息 (WinForms)
- 对于服务或控制台应用程序:将其记录到文件(服务或控制台)
然后我总是将外部运行的每一段代码放在try/catch
中:
- WinForms 基础架构触发的所有事件(加载、点击、SelectedChanged...)
- 第三方组件触发的所有事件
然后我用'try/catch'括起来
Then I enclose in 'try/catch'
- 我所知道的所有操作可能不会一直有效(IO 操作、可能为零除法的计算......).在这种情况下,我会抛出一个新的
ApplicationException("custom message",innerException)
来跟踪真正发生的事情
- All the operations that I know might not work all the time (IO operations, calculations with a potential zero division...). In such a case, I throw a new
ApplicationException("custom message", innerException)
to keep track of what really happened
此外,我会尽力对异常进行正确排序.有以下例外情况:
Additionally, I try my best to sort exceptions correctly. There are exceptions which:
需要立即向用户展示
need to be shown to the user immediately
需要一些额外的处理来在它们碰巧避免级联问题时将它们组合在一起(即:在 TreeView
填充期间将 .EndUpdate 放在 finally
部分中)
require some extra processing to put things together when they happen to avoid cascading problems (ie: put .EndUpdate in the finally
section during a TreeView
fill)
用户并不关心,但知道发生了什么很重要.所以我总是记录它们:
the user does not care, but it is important to know what happened. So I always log them:
在事件日志中
或在磁盘上的 .log 文件中
or in a .log file on the disk
在应用程序顶级错误处理程序中设计一些静态方法来处理异常是一个很好的做法.
It is a good practice to design some static methods to handle exceptions in the application top level error handlers.
我也强迫自己尝试:
- 请记住所有异常都会向上冒泡.没有必要在任何地方都放置异常处理程序.
- 可重用或深度调用的函数不需要显示或记录异常:它们要么自动冒泡,要么在我的异常处理程序中与一些自定义消息一起重新抛出.
- Remember ALL exceptions are bubbled up to the top level. It is not necessary to put exception handlers everywhere.
- Reusable or deep called functions does not need to display or log exceptions : they are either bubbled up automatically or rethrown with some custom messages in my exception handlers.
最后:
不好:
// DON'T DO THIS; ITS BAD
try
{
...
}
catch
{
// only air...
}
没用:
// DON'T DO THIS; IT'S USELESS
try
{
...
}
catch(Exception ex)
{
throw ex;
}
最后尝试没有捕获是完全有效的:
Having a try finally without a catch is perfectly valid:
try
{
listView1.BeginUpdate();
// If an exception occurs in the following code, then the finally will be executed
// and the exception will be thrown
...
}
finally
{
// I WANT THIS CODE TO RUN EVENTUALLY REGARDLESS AN EXCEPTION OCCURRED OR NOT
listView1.EndUpdate();
}
我在顶层做什么:
// i.e When the user clicks on a button
try
{
...
}
catch(Exception ex)
{
ex.Log(); // Log exception
-- OR --
ex.Log().Display(); // Log exception, then show it to the user with apologies...
}
我在一些所谓的函数中做了什么:
What I do in some called functions:
// Calculation module
try
{
...
}
catch(Exception ex)
{
// Add useful information to the exception
throw new ApplicationException("Something wrong happened in the calculation module:", ex);
}
// IO module
try
{
...
}
catch(Exception ex)
{
throw new ApplicationException(string.Format("I cannot write the file {0} to {1}", fileName, directoryName), ex);
}
异常处理(自定义异常)有很多事情要做,但我尽量记住的那些规则对于我所做的简单应用程序来说已经足够了.
There is a lot to do with exception handling (Custom Exceptions) but those rules that I try to keep in mind are enough for the simple applications I do.
这里是一个扩展方法的例子,它以一种舒适的方式处理捕获的异常.它们以可以链接在一起的方式实现,并且很容易添加您自己的捕获异常处理.
Here is an example of extensions methods to handle caught exceptions a comfortable way. They are implemented in a way they can be chained together, and it is very easy to add your own caught exception processing.
// Usage:
try
{
// boom
}
catch(Exception ex)
{
// Only log exception
ex.Log();
-- OR --
// Only display exception
ex.Display();
-- OR --
// Log, then display exception
ex.Log().Display();
-- OR --
// Add some user-friendly message to an exception
new ApplicationException("Unable to calculate !", ex).Log().Display();
}
// Extension methods
internal static Exception Log(this Exception ex)
{
File.AppendAllText("CaughtExceptions" + DateTime.Now.ToString("yyyy-MM-dd") + ".log", DateTime.Now.ToString("HH:mm:ss") + ": " + ex.Message + "
" + ex.ToString() + "
");
return ex;
}
internal static Exception Display(this Exception ex, string msg = null, MessageBoxImage img = MessageBoxImage.Error)
{
MessageBox.Show(msg ?? ex.Message, "", MessageBoxButton.OK, img);
return ex;
}
这篇关于如何使用 try catch 进行异常处理是最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!