Postsharp 重新捕获异常被自己捕获并重新抛出
Postsharp recatch exception beeing caught and rethrown by itself
我希望能够使用 Postsharp OnMethodBoundary.OnException
捕获异常。但只有一次。让我解释一下。
我有这些方法:
public void FooV1(){
throw new NotYetImplementedException();
}
public void FooV2(){
try{
throw new NotYetImplementedException();
} catch(Exception) {
Console.Writeline("Exception has be caught by catch block.");
}
}
还有这个 OnException :
public void OnException(MethodExecutionArgs args){
Console.Writeline("Exception has be caught by Postsharp.");
}
当异常发生时,异常被捕获,我做了一些工作(保存上下文)但我不想干扰程序工作流程。因此,如果在 try catch 块中引发异常,它将被捕获,如果没有,则将引发异常。
如果在OnException(...)
我用args.FlowBehavior = FlowBehavior.Default;
我得到:
在 Foov1 中:
Exception has be caught by Postsharp.
Exception has be caught by Postsharp.
因为当重新抛出的 Postsharp 中的异常重新捕获时(但只有一次?我希望它循环)。我想让 OnException 只被调用一次,如果异常没有在调用堆栈的更高层被捕获,那么程序应该停止。
在 FooV2 中:
Exception has be caught by Postsharp.
Exception has be caught by catch block.
我得到了预期的结果。
我无法使用 FlowBehavior.Continue
或 FlowBehavior.Return
,因为无法到达 catch 块。
我看不出 FlowBehavior.Throw
和 FlowBehavior.Rethrow
之间的区别
我该如何解决?
我不知道您的实际代码是什么,但您可能将 OnException 方面应用于两个或多个方法:抛出原始异常的方法和捕获异常的方法。这可以解释为什么您两次看到 OnException 消息。
当你这样做时
[YourPostSharpOnExceptionAspect]
void A()
{
// code
}
它被翻译成大致如下:
void A()
{
try {
// code
} catch (Exception e) {
yourPostSharpOnExceptionAspectInstance.OnException(e);
throw;
}
}
由于每个 PostSharp 方面不断重新抛出相同的异常,您将多次捕获它。
您可能需要添加自己的代码来仅处理一次异常。你可以这样做:
public void OnException(MethodExecutionArgs args){
if (args.Exception.Data["Handled"]) {
// do nothing, already saved
args.FlowBehavior = FlowBehavior.Rethrow;
}
else
{
// first time seeing this exception, do stuff....
args.Exception.Data["Handled"] = true; // and mark the exception as processed
args.FlowBehavior = FlowBehavior.Throw;
}
}
Throw
和 Rethrow
之间的区别在于 Throw
在代码中添加了类似 throw args.Exception
的内容,而 Rethrow
仅添加了 throw;
重新抛出最初捕获的异常(并保留原始堆栈跟踪)。
我希望能够使用 Postsharp OnMethodBoundary.OnException
捕获异常。但只有一次。让我解释一下。
我有这些方法:
public void FooV1(){
throw new NotYetImplementedException();
}
public void FooV2(){
try{
throw new NotYetImplementedException();
} catch(Exception) {
Console.Writeline("Exception has be caught by catch block.");
}
}
还有这个 OnException :
public void OnException(MethodExecutionArgs args){
Console.Writeline("Exception has be caught by Postsharp.");
}
当异常发生时,异常被捕获,我做了一些工作(保存上下文)但我不想干扰程序工作流程。因此,如果在 try catch 块中引发异常,它将被捕获,如果没有,则将引发异常。
如果在OnException(...)
我用args.FlowBehavior = FlowBehavior.Default;
我得到: 在 Foov1 中:
Exception has be caught by Postsharp. Exception has be caught by Postsharp.
因为当重新抛出的 Postsharp 中的异常重新捕获时(但只有一次?我希望它循环)。我想让 OnException 只被调用一次,如果异常没有在调用堆栈的更高层被捕获,那么程序应该停止。
在 FooV2 中:
Exception has be caught by Postsharp. Exception has be caught by catch block.
我得到了预期的结果。
我无法使用 FlowBehavior.Continue
或 FlowBehavior.Return
,因为无法到达 catch 块。
我看不出 FlowBehavior.Throw
和 FlowBehavior.Rethrow
我该如何解决?
我不知道您的实际代码是什么,但您可能将 OnException 方面应用于两个或多个方法:抛出原始异常的方法和捕获异常的方法。这可以解释为什么您两次看到 OnException 消息。
当你这样做时
[YourPostSharpOnExceptionAspect]
void A()
{
// code
}
它被翻译成大致如下:
void A()
{
try {
// code
} catch (Exception e) {
yourPostSharpOnExceptionAspectInstance.OnException(e);
throw;
}
}
由于每个 PostSharp 方面不断重新抛出相同的异常,您将多次捕获它。
您可能需要添加自己的代码来仅处理一次异常。你可以这样做:
public void OnException(MethodExecutionArgs args){
if (args.Exception.Data["Handled"]) {
// do nothing, already saved
args.FlowBehavior = FlowBehavior.Rethrow;
}
else
{
// first time seeing this exception, do stuff....
args.Exception.Data["Handled"] = true; // and mark the exception as processed
args.FlowBehavior = FlowBehavior.Throw;
}
}
Throw
和 Rethrow
之间的区别在于 Throw
在代码中添加了类似 throw args.Exception
的内容,而 Rethrow
仅添加了 throw;
重新抛出最初捕获的异常(并保留原始堆栈跟踪)。