如何捕获异常

6
这是一个可以妥善处理异常的应用程序,它是一个WCF服务。之前的所有应用都只是为了自己简单创建的。我对C#中的异常处理知识非常有限。
我的代码如下:
MembershipUser memUser = Membership.GetUser(username);

DatabaseDataContext context = new DatabaseDataContext();
UserMembership user = UserMembership.getUserMembership(memUser);
ItemsForUser itemUser = Helper.createItemForUser(ref item, memUser);
Helper.setItemCreationInfo(ref item, user);
context.Items.InsertOnSubmit(item);
context.SubmitChanges();

在这段代码中可能会出现一些异常,例如NullReferenceException。我该如何知道哪个对象引起了异常,以便在catch中知道该做什么并返回给客户端?


您可能会发现这个答案及其中的链接相关:https://dev59.com/rGw05IYBdhLWcg3wmCwo#7152374 - Dmitry
2个回答

9

通常情况下,您不应该捕获任何异常。

我知道这听起来很奇怪,但事实是,您只应该捕获您实际上可以处理的异常,而且通常您无法对异常做出任何处理。

对此规则的“例外”涉及如何“处理”异常。在某些应用程序中,“处理”异常意味着记录它。在其他应用程序中(例如ASP.NET),最好不要处理异常,因为框架(在这种情况下为ASP.NET Health Monitoring)将为您记录它。

在事件驱动的代码中,例如Windows表单,我发现有必要在事件处理程序内部捕获异常。至少在较早的.NET版本中,允许异常传播到按钮单击事件之外会产生不良结果。我通常捕获异常并在对话框中显示它。

在多层应用程序中,您可能会在分层边界处捕获异常,然后重新抛出一个特定于层的异常:

try
{
   // ...
}
catch (Exception ex)
{
    throw new TierException("Some message", ex);
}

另一个用例是捕获异常,然后抛出一个带有更多信息的新异常:

public int GetValueFromConfigurationFile(...)
{
    const string configFileName = "...";
    try
    {
        // ...
    }
    catch (FileNotFoundException fEx)
    {
        throw new InvalidOperationException(
            String.Format("Can't find configuration file {0}", configFileName), 
            fEx);
    }
}

在这种情况下,你正在捕获特定的异常(FileNotFoundException),并提供给调用者一些他们无法知道的信息:未找到的文件是配置文件。
一般的建议是: - 只捕获你知道如何处理的异常 - 尽可能捕获最具体的异常 - 在创建新异常时始终包括内部异常,以保留异常链 - 要重新抛出当前异常,请使用throw;而不是throw ex; 还有一些其他的建议,我会尝试为您找到来自Microsoft Framework设计指南的参考资料。
附言:如果有人能找到这个重复的问题,请随意将其关闭。我不介意失去任何声望。我只是找不到重复的问题。
我应该直接发布“exception-handling”标签的链接,其中写道:

但是,对于.NET程序中的异常处理,请参阅“异常设计指南”。


谢谢,但这实际上不是我的答案。我只需要找到链接。 - John Saunders

1

尽管WCF有机制将服务器异常传递给客户端,但考虑一下您的客户端用户是否真的想在面前看到通常复杂的服务器端异常可能是值得的。
通常更好的方法是跟踪服务器端异常 - 如果您想远程访问它,则使用远程跟踪记录器。或者在服务器上有一个单独的文本跟踪API,以不显眼的方式记录服务器异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接