php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68270 Exception from finally block has exception from try block magically injected
Submitted: 2014-10-20 16:48 UTC Modified: -
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: dan dot lugg at gmail dot com Assigned:
Status: Open Package: *General Issues
PHP Version: 5.5.18 OS: Windows 7 x64
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: dan dot lugg at gmail dot com
New email:
PHP Version: OS:

 

 [2014-10-20 16:48 UTC] dan dot lugg at gmail dot com
Description:
------------
When an exception is thrown from a `finally` block, if an exception has been thrown from the `finally`'s corresponding `try` block, the `finally`-thrown exception magically has the `try`-thrown exception assigned as it's `$previous`.

Test script:
---------------
<?php

try {
	try {
		throw new Exception('Foo');
	}
	finally {
		throw new Exception('Bar');
	}
}
catch(Exception $exception) {
	var_dump($exception);
}

Expected result:
----------------
Not certain, but I'd guess the `finally`-thrown exception should bubble, while the `try`-thrown exception is swallowed? Perhaps a different outcome, but what occurs is both unexpected and undocumented.

Actual result:
--------------
object(Exception)#2 (7) {
  ["message":protected]=>
  string(3) "Bar"
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(9) "/in/9DMoe"
  ["line":protected]=>
  int(8)
  ["trace":"Exception":private]=>
  array(0) {
  }
  ["previous":"Exception":private]=>   <-- How is this here?
  object(Exception)#1 (7) {
    ["message":protected]=>
    string(3) "Foo"
    ["string":"Exception":private]=>
    string(0) ""
    ["code":protected]=>
    int(0)
    ["file":protected]=>
    string(9) "/in/9DMoe"
    ["line":protected]=>
    int(5)
    ["trace":"Exception":private]=>
    array(0) {
    }
    ["previous":"Exception":private]=>
    NULL
  }
}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-10-20 16:53 UTC] Danack at basereality dot com
This happens when the 'previous' value is explicitly set to null as well.

try {
	try {
		throw new Exception('Foo');
	}
	finally {
		throw new Exception('Bar', 0, null);
	}
}
catch(Exception $exception) {
	$actualPrevious = $exception->getPrevious();
	var_dump($actualPrevious);
}


Expected
========

NULL

Actual
======


object(Exception)#1 (7) {
  ["message":protected]=>
  string(3) "Foo"
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(9) "/in/FUjgp"
  ["line":protected]=>
  int(5)
  ["trace":"Exception":private]=>
  array(0) {
  }
  ["previous":"Exception":private]=>
  NULL
}
 [2014-10-20 17:00 UTC] Danack at basereality dot com
It looks like the first construction of an Exception gets the previous, subsequent construction behaves as expected:

Code
----
function foo(){
	try {
		throw new Exception('First exception');
	}
	finally {
		throw new Exception('Bar', 0, new Exception("This shouldn't have a previous."));
	}

}

try {
   foo();
}
catch(Exception $exception) {
	while ($exception = $exception->getPrevious()) {
        echo $exception->getMessage().PHP_EOL;
    }
}


Expected
--------
This shouldn't have a previous.

Actual
------
This shouldn't have a previous.
First exception
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 28 07:01:29 2024 UTC