异常处理的良好实践设计模式

时间:2015-06-25 20:32:48

标签: c# .net design-patterns

我在底层方法的下面代码的每个方法中都有异常处理代码

throw new Exception("The error that happens");

有什么方法可以避免在每种方法中一次又一次地编写这段代码吗?

我正在尝试编写自己的代码而不使用任何日志框架

private void TopLevelMethod()
{
    try
    {
        SomeMethod();
    }
    catch (Exception ex)
    {
        // Log/report exception/display to user etc.
    }
}

private void SomeMethod()
{
    TestPartA();
    TestPartB();
    TestPartC();
    TestPartD();
}

private void TestPartA()
{
    // Do some testing...
    try
    {
        if (somethingBadHappens)
        {
            throw new Exception("The error that happens");
        }
    }
    catch (Exception)
    {
        // Cleanup here. If no cleanup is possible, 
        // do not catch the exception here, i.e., 
        // try...catch would not be necessary in this method.

        // Re-throw the original exception.
        throw;
    }
}

private void TestPartB()
{
    // No need for try...catch because we can't do any cleanup for this method.
    if (somethingshappens)
    {
        throw new Exception("The error that happens");
    }
}

3 个答案:

答案 0 :(得分:3)

如果你想对他们做一些有意义的事情,只捕捉错误,例如:

  1. 使用框架异常包装异常(例如SqlException。ADO.NET从不传递套接字级错误。它会向您传递一个有意义的SQL错误代码)
  2. 清理
  3. 实际响应(例如重试或插入默认值)
  4. 记录几乎不合适。顶级处理程序应该记录。当然不是路径中的每个方法都应该记录。日志和代码是多么混乱。别这么做。

    只是不要吞下错误信息,让错误消失。这样就没有理由在任何地方为错误插入本地日志记录代码。

答案 1 :(得分:1)

如果您更喜欢使用类似代码风格的函数式编程,一种方法是使用回调错误回调。 示例:

    private void SomeMethod()
    {
        // do something
    }
     public bool Execute(Action act, Action<Exception> onErrorCallback)
        {
            var res = true;
            try
            {
                act();
            }
            catch (Exception ex)
            {
                res = false;
                onErrorCallback(ex);
            }
            return res;
        }

并像这样使用Execute

   var successfull = true;
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   if (!successfull)
       ; // show user or something else

答案 2 :(得分:0)

  

Graffito:请举例说明示例.Thankyou ......

您的代码重构:

private void TopLevelMethod()
{ 
    List<string> errors=new List<string>() ;
    if (!SomeMethod(errors)) { /* Log/report errors/display to user etc. */ }
}

private bool SomeMethod(List<string> errors)
{
    return TestPartA(errors) && TestPartB(errors) && TestPartC(errors) && TestPartD(errors);
}

private bool TestPartA(List<string> errors)
{
  bool result = true ;
  try 
  {
    // Do some testing...
    if (somethingBadHappens) { result=false; errors.Add("The error that happens"); }
  }
  catch (Exception ex) { errors.Add("Error in TestPartA: "+Ex.Exception.Message.ToString()) ; }
  return result ;
}

private bool TestPartB(List<string> errors)
{
  bool result = true ;
  // Do some testing...
  if (somethingBadHappens) { result = false ; errors.Add("The error that happens"); }
  return result ;
}