如何明确不抛出异常?

时间:2017-08-23 12:35:43

标签: c# .net exception

这可能是一个广泛的问题,但最近我想知道以下内容:在我们的C#后端,我们有很多地方将一些代码包装在try / catch块中,特别是调用外部WcF服务。其中一些调用对于应用程序至关重要,因此在catch块中我们记录错误并重新抛出,如:

catch(Exception ex)
{
    _logger.Error("Some good error message");
    throw ex;
}

另一方面,我们允许失败的服务,但我们仍然想记录错误,所以它们看起来像:

catch(Exception ex)
{
    _logger.Error("Some good error message");
}

现在阅读团队成员的代码,我不能确定他们是否忘记投掷或者这是否是预期的行为。

问:有没有办法,分别是。什么是默认方式,明确地不重新抛出(不在代码中包含注释)。

我考虑过这样的事情:

catch(Exception ex)
{
    _logger.Error("Some good error message");
    NotThrowingHereOnPurpose();
}

// ...
// and further below a private method
// ...

private void NotThrowingHereOnPurpose(){}

5 个答案:

答案 0 :(得分:3)

这里可能有用的一种方法是更改​​调用您明确允许失败的代码的方式,使其看起来根本不像try / catch

例如,您可以编写一个执行错误报告的辅助方法,并使用表达为lambdas的操作来调用它:

void InvokeFailSafe(Action action, Action<Exception> onFailure = null) {
    try {
        action();
    } catch (Exception e) {
        if (onFailure != null) {
            onFailure(e);
        }
    }
}

现在代替try / catch,你会写下这个:

InvokeFailSafe(
    () => {
        ... The code that may fail
    }
,   exception => _logger.Error("Some good error message: {0}", exception)
);

或者像这样,如果你不想记录任何东西:

InvokeFailSafe(
    () => {
        ... The code that may fail
    }
);

如果您以这种方式编写代码,那么对于缺少throw语句就毫无疑问。

答案 1 :(得分:1)

这是对dasblinkenlight的回答的相反解决方案。而不是通知别人不能重新抛出异常,而是说它必须是。

如果您只想记录它,请照常使用Error方法。否则,您可以为记录器编写扩展方法以记录并抛出异常。

该方法将获取catched异常并使用ExceptionDispatchInfo类重新抛出它。 ExceptionDispatchInfo用于使用原始堆栈跟踪信息和Watson信息重新抛出异常。它的行为类似于throw;(没有指定的异常)。

public static void ErrorAndThrow(this ILogger logger, string message, Exception exception)
{
    var exceptionInfo = ExceptionDispatchInfo.Capture(exception);

    logger.Error(message);
    exceptionInfo.Throw();
}

并以这种方式使用它:

try
{
}
catch (Exception ex)
{
    // ex would be rethrown here
    _logger.ErrorAndThrow("Some good error message", ex);
}

答案 2 :(得分:0)

  问:有没有办法,分别是。什么是默认方式,明确表示NOT   重新抛出(不包括代码中的注释)。

理想的方法不是捕获一般异常。现在,扔或不完全取决于你的情况。您需要了解在发生异常时知道如何处理时使用异常处理。因此,只应处理特定的例外情况。在不知道您捕获的内容的情况下捕获异常将改变应用程序的行为。

  

现在阅读团队成员的代码我不能确定他们是否忘记了   扔或如果这是预期的行为。

这是代码作者可以向您解释的内容。但这是一个学习从这里学习。您的代码应该是自我解释的。在您无法使用代码表达自己的特定情况下,请添加有意义的评论。

您可以查看此link以便更好地理解。

答案 3 :(得分:0)

我实际上找到了另一种方式,包括其他人在此处提出的建议,但使用内置功能:例外过滤器。我可以自由修改here中给出的示例来说明这一点:

public void MethodThatFailsSometimes()
{
    try {
        PerformFailingOperation();
    } 
    catch (Exception e) when (e.LogAndBeCaught())
    {
    }
}

然后可以在Exception上设置两个扩展方法,比如LogAndBeCaughtLogAndEscape,如下所示:

public static bool LogAndBeCaught(this Exception e)
{
    _logger.Error(@"Following exception was thrown: {e}");
    return true;
} 

public static bool LogAndEscape(this Exception e)
{
    _logger.Error(@"Following exception was thrown: {e}");
    return false;
} 

答案 4 :(得分:-1)

这不应该经常出现。考虑

string WebGreeting()
{
  try
  {
     return _greetingService.HelloWorld();
  }
  catch(Exception ex)
  {
      _logger.Error("Some good error message");
      //throw;  // when this is missing, you get the compiler error "not all paths ..."
  }
  // unless you very deliberately code the on-error case
  // return "nothing";
}

这样就留下了奇怪的void方法。但这真的是你的问题吗?