[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>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.