[DOC-CVS] [doc-en] master: Document exception chaining (#3855)
[email protected] (Grégoire Paris via GitHub)
| Newsgroups | php.doc.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Grégoire Paris (greg0ire)
Committer: GitHub (web-flow)
Pusher: DanielEScherzer
Date: 2025-06-23T14:41:19-07:00
Commit: https://github.com/php/doc-en/commit/ed956d714e3fcf42b90c23777b0eb105c681b97c
Raw diff: https://github.com/php/doc-en/commit/ed956d714e3fcf42b90c23777b0eb105c681b97c.diff
Document exception chaining (#3855)
This is already documented as a user note, but the note does not explain
what happens if both exceptions already have a previous exception.
Here is what I believe is the related piece of code:
```
/* Chain potential exception from wrapping finally block */
if (Z_OBJ_P(fast_call)) {
if (ex) {
if (zend_is_unwind_exit(ex) || zend_is_graceful_exit(ex)) {
/* discard the previously thrown exception */
OBJ_RELEASE(Z_OBJ_P(fast_call));
} else {
zend_exception_set_previous(ex, Z_OBJ_P(fast_call));
}
} else {
ex = EG(exception) = Z_OBJ_P(fast_call);
}
}
```
The note: https://www.php.net/manual/en/language.exceptions.php#129177
Changed paths:
M language/exceptions.xml
Diff:
diff --git a/language/exceptions.xml b/language/exceptions.xml
index d81e4e8b38ed..483331d03fa5 100644
--- a/language/exceptions.xml
+++ b/language/exceptions.xml
@@ -79,6 +79,12 @@
is executed. Additionally, if the &finally; block also contains a &return; statement,
the value from the &finally; block is returned.
</para>
+ <para>
+ Another notable interaction is between an exception thrown from within a &try; block,
+ and an exception thrown from within a &finally; block. If both blocks throw an exception,
+ then the exception thrown from the &finally; block will be the one that is propagated,
+ and the exception thrown from the &try; block will used as its previous exception.
+ </para>
</sect1>
<sect1 annotations="chunk:false" xml:id="language.exceptions.exception-handler">
@@ -359,6 +365,38 @@ try {
<screen>
<![CDATA[
It did not work
+]]>
+ </screen>
+ </example>
+ <example>
+ <title>Exception in try and in finally</title>
+ <programlisting role="php">
+<![CDATA[
+<?php
+
+try {
+ try {
+ throw new Exception(message: 'Third', previous: new Exception('Fourth'));
+ } finally {
+ throw new Exception(message: 'First', previous: new Exception('Second'));
+ }
+} catch (Exception $e) {
+ var_dump(
+ $e->getMessage(),
+ $e->getPrevious()->getMessage(),
+ $e->getPrevious()->getPrevious()->getMessage(),
+ $e->getPrevious()->getPrevious()->getPrevious()->getMessage(),
+ );
+}
+]]>
+ </programlisting>
+ &example.outputs;
+ <screen>
+<![CDATA[
+string(5) "First"
+string(6) "Second"
+string(5) "Third"
+string(6) "Fourth"
]]>
</screen>
</example>