在维护我同事的代码时,甚至有人声称自己是高级开发人员,我经常看到以下代码:

try
{
  //do something
}
catch
{
  //Do nothing
}

或者有时他们将日志信息写入日志文件,例如下面的try catch块

try
{
  //do some work
}
catch(Exception exception)
{
   WriteException2LogFile(exception);
}

我只是想知道他们所做的是不是最好的做法?这让我很困惑,因为在我看来,用户应该知道系统发生了什么。


当前回答

第二种方法很好。

如果你不想显示错误,并通过显示运行时异常(即。错误),这与他们无关,然后只记录错误,技术团队可以寻找问题并解决它。

try
{
  //do some work
}
catch(Exception exception)
{
   WriteException2LogFile(exception);//it will write the or log the error in a text file
}

我建议您对整个应用程序采用第二种方法。

其他回答

第二种方法很好。

如果你不想显示错误,并通过显示运行时异常(即。错误),这与他们无关,然后只记录错误,技术团队可以寻找问题并解决它。

try
{
  //do some work
}
catch(Exception exception)
{
   WriteException2LogFile(exception);//it will write the or log the error in a text file
}

我建议您对整个应用程序采用第二种方法。

最佳实践是在错误发生时抛出异常。因为发生了一个错误,它不应该被隐藏。

但在现实生活中,你可以有几种情况想要隐藏它

您依赖于第三方组件,并且希望在出现错误时继续执行程序。 您有一个业务案例,需要继续进行,以防出现错误

我知道这是一个老问题,但这里没有人提到MSDN的文章,实际上是文档为我澄清了这个问题,MSDN在这方面有一个非常好的文档,当以下条件为真时,你应该捕获异常:

您已经很好地理解了异常可能被抛出的原因,并且可以实现特定的恢复,例如在捕获FileNotFoundException对象时提示用户输入一个新的文件名。 您可以创建并抛出一个新的、更具体的异常。

int GetInt(int[] array, int index)
{
    try
    {
        return array[index];
    }
    catch(System.IndexOutOfRangeException e)
    {
        throw new System.ArgumentOutOfRangeException(
            "Parameter index is out of range.");
    }
}

您希望在将异常传递给其他处理之前对其进行部分处理。在下面的示例中,catch块用于在重新抛出异常之前向错误日志添加条目。

    try
{
    // Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
    // Call a custom error logging procedure.
    LogError(e);
    // Re-throw the error.
    throw;     
}

我建议阅读整个“异常和异常处理”部分以及异常的最佳实践。

我的异常处理策略是:

通过连接到应用程序来捕获所有未处理的异常。线程异常事件,然后决定: 对于UI应用程序:向用户弹出一个道歉消息(WinForms) 对于服务或控制台应用程序:将其记录到文件(服务或控制台)

然后我总是在try/catch中附上外部运行的每一段代码:

WinForms基础架构触发的所有事件(加载、单击、选定更改…) 由第三方组件触发的所有事件

然后加上try/catch

我所知道的所有操作可能并不总是有效(IO操作,潜在的零除法计算……)。在这种情况下,我抛出一个新的ApplicationException(“自定义消息”,innerException)来跟踪实际发生的事情

此外,我尽最大努力对异常进行正确排序。但也有例外:

需要立即显示给用户 当它们发生时,需要一些额外的处理来将它们放在一起,以避免级联问题(例如:在TreeView填充期间将. endenddate放在finally部分) 用户并不关心,但重要的是要知道发生了什么。所以我总是记录它们: 在事件日志中 或者在磁盘上的.log文件中

在应用程序顶级错误处理程序中设计一些静态方法来处理异常是一个很好的实践。

我还强迫自己试着:

记住,所有的异常都被冒泡到顶层。没有必要把异常处理程序放在任何地方。 可重用的或深度调用的函数不需要显示或记录异常:它们要么自动生成,要么在异常处理程序中使用一些自定义消息重新抛出。

最后:

Bad:

// DON'T DO THIS; ITS BAD
try
{
    ...
}
catch 
{
   // only air...
}

用处:

// DON'T DO THIS; IT'S USELESS
try
{
    ...
}
catch(Exception ex)
{
    throw ex;
}

have a try finally without a catch是完全正确的:

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...
}

我在一些被调用的函数中所做的:

// 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);
}

异常处理(自定义异常)有很多事情要做,但我试图记住的那些规则对于我做的简单应用程序已经足够了。

下面是一个扩展方法的例子,它以一种舒适的方式处理捕获的异常。它们以一种可以链接在一起的方式实现,并且非常容易添加您自己捕获的异常处理。

// 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 + "\n" + ex.ToString() + "\n");
    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;
}

留下空白的catch块是最糟糕的做法。如果出现错误,最好的处理方法是:

登录到文件数据库等。 尝试在飞行中修复它(可能尝试做该操作的替代方式) 如果我们不能修复这个问题,那么就通知用户有错误,当然还要中止操作