获取 PL/SQL 中重新抛出异常的完整堆栈跟踪(从点异常开始)

Posted

技术标签:

【中文标题】获取 PL/SQL 中重新抛出异常的完整堆栈跟踪(从点异常开始)【英文标题】:Getting full stack trace for re-thrown exception in PL/SQL (from the point exception originated) 【发布时间】:2017-07-18 17:29:11 【问题描述】:

我在PL/SQL 中有几个嵌套块,如果发生错误,我只想在最顶层处理错误,方法是在每个嵌套级别的途中重新抛出错误。每当我在内部块中重新抛出 (RAISE) 异常时,DBMS_UTILITY.FORMAT_ERROR_BACKTRACE 会将堆栈重置到最后引发异常的点(这是通往顶层的嵌套块之一)。我找不到从异常最初发生的地方获取完整堆栈跟踪的方法。除了在重新抛出中间块之前记录之外,任何想法如何获得完整的堆栈跟踪?

【问题讨论】:

捕获并重新抛出异常会将错误堆栈重置到再次引发的位置。你为什么要首先屏蔽异常,如果异常没有在内部块中处理,它将自动传播到下一级/外部块,直到具有正确错误和它起源的行的顶层。 中间块记录异常。 为什么,如果您不处理中间块中的错误以捕获它并重新引发它,那又有什么意义呢。异常会自动通过中间块传播到可以处理的顶层。 没有必要通过中间块显式地重新提升它,因为它会自动/隐式地“重新提升”到顶层块。 我知道传播,再次需要捕获异常并记录每个中间块。 【参考方案1】:

我知道您要做什么,并且我同意 ivanzg 的观点,即不需要这样做 - 在***处理程序中,您可以将整个调用堆栈回溯到程序和错误行。

RAISE 语句是你正在做的事情的杀手。一旦你这样做了,你就失去了真正的错误位置。

【讨论】:

【参考方案2】:

实际上,要获取完整的调用堆栈,请结合使用 DBMS_UTILITY.FORMAT_CALL_STACK() 和 DBMS_UTILITY.FORMAT_ERROR_BACKTRACE()。 FORMAT_CALL_STACK 将显示对错误处理程序的***调用,而 FORMAT_ERROR_BACKTRACE 将(准确)显示从错误处理程序到错误过程和代码行。

FORMAT_CALL_STACK 的唯一缺点是行号不一定是您所期望的 - 它们将您指向错误处理程序。

【讨论】:

以上是关于获取 PL/SQL 中重新抛出异常的完整堆栈跟踪(从点异常开始)的主要内容,如果未能解决你的问题,请参考以下文章

在不丢失堆栈跟踪的情况下重新抛出 Java 中的异常

抛出异常时如何获取 JavaScript 堆栈跟踪?

如何在 C# 中重新抛出 InnerException 而不会丢失堆栈跟踪?

获取完整的字符串堆栈跟踪,包括内部异常

C#重新抛出异常:如何在IDE中获取异常堆栈?

抑制预期 Oracle 异常的 PHP 警告