简体   繁体   English

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

[英]Good practice design pattern for Exception handling

I have exception handling code in every method for the below code for the bottom level methods 我在底层方法的下面代码的每个方法中都有异常处理代码

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

Is there any way I can avoid writing this code again and again in each method? 有什么办法可以避免在每种方法中一次又一次地编写这段代码吗?

I am trying to write my own code and not using any log frameworks 我正在尝试编写自己的代码而不使用任何日志框架

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

Only catch errors if you want to do something meaningful to them such as: 如果你想对他们做一些有意义的事情,只捕捉错误,例如:

  1. Wrapping the exception with a framework exception (eg SqlException . ADO.NET never passes you socket-level errors. It passes you a meaningful SQL error code) 用框架异常包装异常(例如SqlException永远不会传递给你的套接字级错误。它会传递一个有意义的SQL错误代码)
  2. Cleanup 清理
  3. Actually responding (eg retry, or insert default values) 实际上响应(例如重试或插入默认值)

Logging is almost never appropriate. 记录几乎从不合适。 The top level handler should log. 顶级处理程序应该记录。 Certainly not every method in the path should log. 当然不是路径中的每个方法都应该记录。 What a clutter for logs and for the code. 日志和代码是多么混乱。 Don't do that. 不要那样做。

Simply don't swallow error information and let the error bubble out. 只是不要吞下错误信息,让错误消失。 That way there is no reason left to insert local logging code for errors everywhere. 这样就没有理由在任何地方插入本地日志记录代码来处理错误。

If you prefer using Functional Programming like code style one way is to use callback error callbacks. 如果您更喜欢使用类似代码风格的函数式编程,一种方法是使用回调错误回调。 Example : 示例:

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

And use Execute like this: 并像这样使用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... Graffito:请你举个示例代码示例.Thankyou ......

Your code refactored: 您的代码重构:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM