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

本文关键字:设计模式 异常处理 | 更新日期: 2023-09-27 17:59:41

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

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

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

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

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

日志记录几乎从来都不合适。顶级处理程序应该进行日志记录。当然,并不是路径中的每个方法都应该进行日志记录。日志和代码真是一团糟。不要那样做。

不要轻信错误信息,让错误冒出来。这样就没有理由在任何地方插入错误的本地日志记录代码。

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

    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

涂鸦:请你举一个示例代码。谢谢。。。

您的代码重构:

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