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

Good practice design pattern for Exception handling

对于底层方法的以下代码,我在每个方法中都有异常处理代码

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

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

    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

Graffito: Would you please give sample code example.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 ;
}

只有在您想对它们做一些有意义的事情时才捕获错误,例如:

  1. 用框架异常包装异常(例如 SqlException。ADO.NET 永远不会传递套接字级错误。它传递给你一个有意义的 SQL 错误代码)
  2. 清理
  3. 实际响应(例如重试或插入默认值)

日志记录几乎从来都不合适。顶级处理程序应该记录。当然不是路径中的每个方法都应该记录。日志和代码多么混乱。不要那样做。

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