繁体   English   中英

捕获不同方法引发的相同异常?

[英]Catching same exception thrown by different methods?

看看下面的代码,其中两个方法抛出相同类型的异常但完全具有不同的上下文。

class Test
{
 public void methodThrowingExceptionX()
 {
   //some code
   throw new X();
 }

 public void anotherMethodThrowingExceptionX()
 {
   //some code
   throw new X();  
 }
}
class TestClient
{
  private Test testObj = new Test();
  public Response TestMethodCaller() 
  {
    try
    {
       testObj.methodThrowingExceptionX();
       testObj.anotherMethodThrowingExceptionX();
    }

    catch(X xExceptionObj)
    {
      //this will catch X exception regardless from which method it is comming
      //How can i distinguish from where the exception is coming(which method is throwing)
      //so that i can return the Response object according to the context of the method which has thrown this exception?
    }
  }
}

其中我正在与上述具有问题catch是,它捕捉型的异常X从两种方法。 但是,当X异常来自不同的方法时,我的高级逻辑需要具有不同的Response对象(例如,具有不同的语言代码,不同的消息,异常原因的不同应用程序特定代码),或者您可以说Responose应根据上下文进行更改。

实现这一目标的最佳方法是什么?

编辑

以下代码告诉您我为什么要这样做

interface ICommand
{
    void execute();
}

//say we have some command implementation
class CommandA : ICommand 
{
  public void execute()
  {

    //some code 
    throw new X();
  }

}

class CommandB : ICommand 
{
  public void execute()
  {

    //some code 
    throw new X();
  }

}
class MacroCommand : ICommand
{
    List<ICommand> commands;

    public MacroCommand(List<ICommand> commands)
    {
        this.commands = commands;

    }
    public void execute()
    {
       foreach(ICommand command in commands)
       {

           //execute method of various commands can throw exceptions may of     same type say X.
           command.execute();
       }
    }
}

class Client
{

   List<ICommand> commands = new List<ICommand>();

   commands.Add(new CommandB());
   commands.Add(new CommandA());

   MacroCommand macroCommand = new MacroCommand(commands);

   try
   {

        macroCommand.execute();
   }

   catch(X xExceptionObj)
   {
     //How can i get the information which execute() actually thrown the exception??

   }

}

通常的方法是使用自己的try...catch包围两个方法调用。 在这种情况下,您始终知道导致异常的原因,您可以单独处理它。

如果你想避免这种不管什么原因,你可以使用Exception.TargetSite

try
{
    testObj.methodThrowingExceptionX();
    testObj.anotherMethodThrowingExceptionX();
}
catch (X xExceptionObj)
{
    MethodBase site = xExceptionObj.TargetSite;

    switch (site.Name)
    {
        case nameof(testObj.methodThrowingExceptionX):
            return blah....
        case nameof(testObj.anotherMethodThrowingExceptionX):
            return blub....
        default:
            throw new Exception("Unexpected method caused exception: " + site.Name);
    }
}

实现这一目标的唯一简洁方法是有2个try..catch块,每个调用一个。

一个丑陋/不可维护/不守规矩的解决方案是使用状态变量并在catch块中检查。

有两种方法,一种是使用包含完整调用层次结构的xExceptionObj.StackTrace,因此可以从该信息中搜索所需的详细信息。 如果多个父级调用相同的方法并且您希望将其作为基类的一部分处理,则首选此方法。

在此输入图像描述

然后,我喜欢的简单案例就是使用TargetSite Object

xExceptionObj.TargetSite.Name

输出将是"methodThrowingExceptionX" 在此输入图像描述

编辑完成后

在宏执行中,您有机会丰富或封装异常:

public void execute()
{
   foreach(ICommand command in commands)       
   {
       try
       {
         command.execute();
       }
       catch(X ex)
       {
          // add one or more command related pieces of info to the exception
          ex.Data.Add("Command", command.Name);
          throw;
       }
   }
}

然后当你处理更高的异常时,你可以从ex.Data["Command"]返回你的ICommand

另一种方法是class XWrapper : Exception ,你可以在其中添加自己的属性,然后替换throw; throw new XWrapper(..., ex); 当然,你必须catch(Xwrapper xObj) ...在循环之外。

暂无
暂无

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

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