Bug #74569 [Com]: Return in a finally clause silently ignores an exception thrown in a try clause

From: Date: Thu, 11 May 2017 14:21:10 +0000
Subject: Bug #74569 [Com]: Return in a finally clause silently ignores an exception thrown in a try clause
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-209058@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=74569&edit=1 ID: 74569 Comment by: trianman at gmail dot com Reported by: trianman at gmail dot com Summary: Return in a finally clause silently ignores an exception thrown in a try clause Status: Open Type: Bug Package: Scripting Engine problem Operating System: Any PHP Version: 7.1.4 Block user comment: N Private report: N New Comment: > btw The behaviour in PHP is the same as that which happens in Java > This behaviour is also that used in Javascript. Sorry to hear that, but AFAIK nor Java nor JavaScript (ECMAScript) has no conventional (standartized) way to produce non critical warnings at the run time. So PHP is better in this way and why can't we employ it? > "Don't put returns in finally" I believe that the good tool must help its users not to "shoot themselves" as much as possible. So the user becomes free from a lot of "Don't do something somewhere". If you don't agree you are free to use an assembler to do anything you want and remember a lot of such restrictions. I can imagine another more expectable an clear way to handle this case. But it will break a BC so can be implemented only in a new major release of PHP. Triggering E_NOTICE is the most convenient way for now. Previous Comments: ------------------------------------------------------------------------ [2017-05-11 13:42:04] danack@php.net This behaviour is also that used in Javascript. function foo() { try { throw 42; } finally { return "edge cases are hard"; } }; alert(foo()); ------------------------------------------------------------------------ [2017-05-11 13:30:49] danack@php.net > but it MUST NOT be silently dropped out. That's a conclusion without rigorous justification. btw The behaviour in PHP is the same as that which happens in Java: https://web.archive.org/web/20070922061412/http://weblogs.java.net/blog/staufferjames/archive/2007/06/_dont_return_in.html It'd be a lot easier to say "Don't put returns in finally blocks, yo". > The interpreter should trigger an E_NOTICE or something similar here. This would almost certainly be better done with code analysis tools, rather than giving warnings on valid (though highly surprising) code. ------------------------------------------------------------------------ [2017-05-11 07:41:34] olavisau at gmail dot com The correct way of writing this would be to catch the exception and throw it again, however this also fails. If it is not thrown again, then the behavior is correct. <?php class MyException extends Exception { public function __construct($message = "", $code = 0, Throwable $previous = null) { parent::__construct($message, $code, $previous); print "2. Exception constructed\n"; } } function throw_exception() { try { throw new MyException("5. Exception message\n"); } catch(Exception $exception) { print "3. Exception caught and thrown again\n"; throw $exception; } finally { return "4. Return statement\n"; } } try { print "1. Start\n"; print throw_exception(); } catch (Exception $e) { print $e->getMessage(); } The flow should be: exception is thrown, caught by the inner block, thrown again, caught by the outer block and then the finally block should execute, returning the flow to print throw_exception(); ------------------------------------------------------------------------ [2017-05-10 16:44:47] trianman at gmail dot com Description: ------------ Return in a finally clause silently ignores an exception thrown in a try clause. I understand that there is no way to handle an exception here, but it MUST NOT be silently dropped out. The interpreter should trigger an E_NOTICE or something similar here. Looks like any version of PHP from 5.6 to 7.1.4 behaves in the same manner: https://3v4l.org/C16rP Here is a similar issue: https://bugs.php.net/bug.php?id=68270 Test script: --------------- <?php class MyException extends Exception { public function __construct($message = "", $code = 0, Throwable $previous = null) { print "2. Exception constructor\n"; parent::__construct($message, $code, $previous); } } function ololo() { try { print "1. Start\n"; throw new MyException("4. Exception message\n"); } finally { return "3. Return statement\n"; } } try { print ololo(); } catch (Exception $e) { print $e->getMessage(); } Expected result: ---------------- 1. Start 2. Exception constructor PHP NOTICE: Dropped exception due the return statement in a finally block 3. Return statement Actual result: -------------- 1. Start 2. Exception constructor 3. Return statement ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=74569&edit=1

« previous php.bugs (#209058) next »