繁体   English   中英

有什么比以下处理异常更好的方法?

[英]What is a better way to handle exceptions than the following?

起初,我打算执行以下操作:

public void WriteToFile(string filePath, string contents)
{
    try
    {
        File.WriteAllText(filePath, contents)
    }
    catch(Exception ex)
    {
        //Log error
    }
}

但后来我决定捕获方法 WriteAllText 的所有特定异常,如下所示:

public void WriteToFile(string filePath, string contents)
{
    try
    {
        File.WriteAllText(filePath, contents);
    }
    catch (IOException ex)
    {
        //An I/O error occured when opening the file
    }
    catch (ArgumentException ex)
    {
       //The exception that is thrown when one of the arguments provided to a method   
         that is not valid.
    }
    catch (UnauthorizedAccessException ex)
    {
       //Unauthorized access
    }
    catch (SecurityException ex)
    {
        //Security exception
    }
    catch (NotSupportedException ex)
    {
        //Invoked method not supported
    } 
}

以上内容非常冗长,使用其他方法可能会更多。 有没有更好的方法来做到这一点,所以我不必写这么多的 catch 语句。 另外,如果捕获到异常,最好从它返回,记录它。 我总是对如何处理它感到困惑。

我注意到一些混乱。 我将处理异常,我没有处理异常以保持简短。 我将使用 ex 变量。 问题更多是关于只做 catch(Exception ex) 或多个 catch 语句。

我也提出了这一点,因为我总是在这里,处理特定的异常而不是包罗万象要好。 如果我误解了这一点,请澄清它的含义。

这取决于您如何处理异常。 例如,如果 SecurityException 将导致您向用户显示一个对话框以提供他们的凭据,那么您应该有一个单独的 catch 子句。 如果不是,则无需明确将它们全部调用。

例如

try
{
    File.WriteAllText(filePath, contents);
}
catch (SecurityException ex)
{
    //present dialog
}
catch (Exception ex)
{
    //All other exceptions handled the same
} 

通常,您的 try/catch 语句将比您在问题中显示的调用堆栈更靠前。 这有两个主要原因。 首先是低级方法不知道如何处理其中发生的异常,因为它没有足够的上下文。 如果低级方法(例如保存文档的方法)确实了解其环境以处理异常,那么这就是抽象泄漏的标志。 其次是更高级别的程序流程将取决于保存操作是否成功。 由于这些原因,最好在最高级别处理所有这些类型的异常,例如在 UI 层中。

也就是说,有时一长串例外——正如你所拥有的——正是通往 go 的方式。 如果你需要处理一堆不同的情况,那么它需要一堆不同的 catch 语句,这就是它的方式。

然而,其中一些异常不需要被捕获。 例如,永远不需要捕获 ArgumentException。 相反,最好每次都通过正确的 arguments。 唯一需要捕获 ArgumentException 的情况是,如果您正在调用一个设计不佳的库,在该库中您事先无法知道参数是否正确。 一个设计良好的库将为此提供替代方案。

因此,只需审慎地检查每种异常类型的情况并确定实际预期会发生哪些异常,就可以缩短 catch 语句的列表。

我同意上面的 SLaks。 如果您不处理它,则没有理由捕获特定异常。 如果您可以处理某些异常但不能处理其他异常,那么您应该有一个 catch all 至少记录有关异常的重要信息。

最好的方法很大程度上取决于您的应用程序的性质和用户的期望。 如果您正在创建一个文字处理应用程序并且您的上述操作是保存用户的文档,那么在不通知用户的情况下吞下异常并记录将是非常糟糕的,在这种情况下。 我会捕获特定的异常,以便更好地向用户报告问题所在。

相反,如果您保存的文件是非关键文件,例如,在 memory 中保留的某些数据的周期缓存,您可能只想简单地记录而不通知用户。 在这种情况下,我将 go 用于通用包罗万象,并仅记录异常详细信息。

暂无
暂无

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

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