使用条件异常处理调试回原始错误,即重新抛出

Posted

技术标签:

【中文标题】使用条件异常处理调试回原始错误,即重新抛出【英文标题】:Debugging back to original error with conditional exception handling, i.e. rethrow 【发布时间】:2012-05-03 10:08:09 【问题描述】:

据我所知,在 Matlab 中,没有有条件地捕获异常的好方法(如果我错了,请纠正我)。唯一的方法是捕获异常,检查标识符,如果无法处理此特定错误,则重新抛出错误。这是可以接受的,虽然不方便。但是,当我使用 Matlabs dbstop if error 时,我最终会出现在 ME.rethrow() 行。然后我无法dbup 回到导致原始错误的地方。

function test_excc

try
    sub_test()
catch ME
    if strcmp(ME.identifier, 'test:notsobad')
        fprintf(1, 'Fine\n');
    else
        ME.rethrow();
    end
end

end

function sub_test
sub_sub_test();
end

function sub_sub_test()
if rand>0.5
    error('test:error', 'Noooo!');
else
    error('test:notsobad', 'That''OK');
end
end

示例用法:

>> test_excc()
Error using test_excc>sub_sub_test (line 21)
Noooo!

Error in test_excc>sub_test (line 16)
sub_sub_test();

Error in test_excc (line 4)
    sub_test()

9           ME.rethrow();
K>> dbstack
> In test_excc at 9

虽然 Matlab 桌面环境将整个堆栈跟踪打印回sub_sub_test,但调试器并没有让我能够上堆栈跟踪并在此函数内部进行调试。

我知道dbstop if caught error。但是,这将调试到 any 捕获的错误,如果软件大量使用异常,则可能会出现很多错误。我只想在未捕获的错误上停止,但我想在产生错误的地方停止——而不是在重新抛出错误的地方。

我的问题:

在 Matlab 中,如何有条件地捕获错误(基于错误标识符)并调试到最初引发错误的地方?

【问题讨论】:

【参考方案1】:

我猜你不能这样做。一旦执行进入catch 语句,dbstack 将不得不引用catch 内的那个位置,因此调试错误原因所需的信息丢失了。 ME.stack 会告诉您异常来自何处,但这不足以在该位置进行调试。

所以我怀疑你可以通过在 catch 中做一些聪明的事情来解决问题。查看 catch 的文档,似乎也没有办法实现 java 风格的catch (ExceptionType ME)

通过以编程方式使用调试命令,可能有一些巧妙的方法可以解决这个问题。例如,S = dbstatus 保存调试状态,如果有办法从保存的状态恢复,那么您可以将其附加到异常中。但我找不到任何记录在案的方法。

【讨论】:

在我调用 ME.rethrow() 的那一刻,Matlab 解释器确实将整个回溯输出到屏幕。所以此时信息在某处。尽管实际访问此信息可能没有记录,但不受支持... 我不认为所有的 debug 信息都可用。只有堆栈跟踪存储在 ME 中。要在代码中的某个位置进行调试,您需要更多关于状态的信息。如果你有 catch ME; my_function(); ME.rethrow(); end; 之类的东西,你可以在重新抛出之前在 catch 内做很多事情——如果发生异常,调试器必须能够从 my_function() 内的任何地方进行调试,因此调试器状态必须继续更新在捕获到异常之后,我猜。 当我最后一次不得不这样做时,我通过编写包含大量子函数和一种主函数来将巨大的 switch 语句保存在 catch 中的代码来解决这个问题。所以:ME.identifier 或 ME.message 上的某些 strcmp 会有条件地将某些内容发送回我例程的不同部分。这是非常 hacky,但至少它有效....

以上是关于使用条件异常处理调试回原始错误,即重新抛出的主要内容,如果未能解决你的问题,请参考以下文章

AppDomain.UnhandledException 自动重新抛出已处理的异常

PHP将抛出一个错误问题,怎么解决

有效处理Java异常三原则

业务层错误和服务层处理——最好的方法?

事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务

异常--常见处理方式,异常安全规范