微软,请不要使用 Try/Catch


发布者 ourjs  发布时间 1388888503000
关键字 心得体会 

作者:karlseguin  译者:myownghost

异常处理已经被讨论十几年了。尽管在怎样处理异常方面有一些普遍共识,但在使用方面还是有一些分歧。不恰当的异常处理很容易被发现,很容易被避免,这是评价代码质量的一个很重要的指标。我知道任何事情都没有绝对一说,但一条普通的规则就是不要使用try/catch。

如果异常发生,你需要非常了解它产生的原因。如果一个意料之外的异常产生了。你还是让程序自己崩溃吧。在大多数Web应用上就是这么干的,一个用户的连接产生了异常不会影响其它用户。(注:这篇文章发表的比较早,在NodeJS及其他单线非阻塞异步编程中,一个线程崩溃了可能会影响到其它程序,不过现在已经有了比较好的解决方案,如Express,持久化session等)。所以最好的方法是做一个全局的异常日志,来记录那些未处理的异常。我经常看到程序员写处理错误的代码,以提高系统的质量。但用户会抱怨系统不稳定,但程序员想破脑袋也不知道到底是什么地方出了问题。

遗憾的是,在有些框架中他们也加了try/catch,看看下面的这个例子,在微软的基础框架里:

private void LoadImage()
{
    if (this.image != null)
    {
        this.image.Dispose();
    }
    

    if (source != null)
    {
        try
        {
            source = Path.Combine(Canvas.ApplicationPath, source);
            image = new Bitmap(source);

           IImagingFactory factory = ImagingFactory.GetImaging();
           factory.CreateImageFromFile(source, out imagingImage);
        }
        catch{}
    }
}

这段代码截自Micrsoft的.NET Compact Framework的前端基础框架(UI Framework)。上面的代码葬送了他们的框架,但这个东西被各种API调用,还广泛使用了。这是非常简单可怕的代码。为什么么他们能容忍异常从这段代码里产生?这段代码意思着如果我读取了一个不存在的图片,如"images/critical_warning.png",程序会继续运行。这可能是你想要的一种情况,但不是所有情况,这样的逻辑应该由应用程序处理,而不是在框架里面。

真正需要异常的地方只有一个,就是全局异常捕捉日志,这样可以帮助你找到所有异常产生的根本原因,并解决掉他们,然后你就可以安心睡大觉了。

一个使用try/catch来掩盖异常的系统不是一个健康的系统。





回复 (1)
  • #
  • #1 谭计伞 1411885760165

    片面。假如你是一个复杂的系统,全部交给全局,排查是很困难的(除非整个系统的代码都很熟悉),尤其维护人员不是开发人员或没有代码的时候。

微信扫码 立即评论