From d74b7e424f704ea73ac97fb1300bb9d4edd8cdc2 Mon Sep 17 00:00:00 2001 From: Tony Levi Date: Mon, 3 Aug 2015 16:16:03 +0930 Subject: [PATCH] MDL-52284 core: compatibility with Exception/Throwable changes in PHP7 --- backup/util/settings/tests/settings_test.php | 6 ++++++ lib/dml/moodle_database.php | 8 ++++++-- lib/dml/moodle_transaction.php | 4 ++-- lib/phpunit/classes/advanced_testcase.php | 8 +++++++- lib/phpunit/classes/basic_testcase.php | 9 ++++++++- lib/phpunit/classes/database_driver_testcase.php | 8 +++++++- lib/setuplib.php | 8 +++++++- 7 files changed, 43 insertions(+), 8 deletions(-) diff --git a/backup/util/settings/tests/settings_test.php b/backup/util/settings/tests/settings_test.php index 201d29e43b2..a50023c03d1 100644 --- a/backup/util/settings/tests/settings_test.php +++ b/backup/util/settings/tests/settings_test.php @@ -126,6 +126,8 @@ class backp_settings_testcase extends basic_testcase { } catch (exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'incorrect_object_passed'); + } catch (TypeError $e) { + // PHP7 will catch type errors for us. } restore_error_handler(); @@ -140,6 +142,8 @@ class backp_settings_testcase extends basic_testcase { } catch (exception $e) { $this->assertTrue($e instanceof base_setting_exception); $this->assertEquals($e->errorcode, 'incorrect_object_passed'); + } catch (TypeError $e) { + // PHP7 will catch type errors for us. } restore_error_handler(); @@ -302,6 +306,8 @@ class backp_settings_testcase extends basic_testcase { } catch (exception $e) { $this->assertTrue($e instanceof backup_setting_exception); $this->assertEquals($e->errorcode, 'incorrect_object_passed'); + } catch (TypeError $e) { + // PHP7 will catch type errors for us. } restore_error_handler(); diff --git a/lib/dml/moodle_database.php b/lib/dml/moodle_database.php index fee0eca089f..78b11df710b 100644 --- a/lib/dml/moodle_database.php +++ b/lib/dml/moodle_database.php @@ -2431,10 +2431,14 @@ abstract class moodle_database { * automatically if exceptions not caught. * * @param moodle_transaction $transaction An instance of a moodle_transaction. - * @param Exception $e The related exception to this transaction rollback. + * @param $e The related exception/throwable to this transaction rollback. * @return void This does not return, instead the exception passed in will be rethrown. */ - public function rollback_delegated_transaction(moodle_transaction $transaction, Exception $e) { + public function rollback_delegated_transaction(moodle_transaction $transaction, $e) { + if (!($e instanceof Exception) && !($e instanceof Throwable)) { + // PHP7 - we catch Throwables in phpunit but can't use that as the type hint in PHP5. + $e = new \coding_exception("Must be given an Exception or Throwable object!"); + } if ($transaction->is_disposed()) { throw new dml_transaction_exception('Transactions already disposed', $transaction); } diff --git a/lib/dml/moodle_transaction.php b/lib/dml/moodle_transaction.php index 106ffb8da5e..a9484419c73 100644 --- a/lib/dml/moodle_transaction.php +++ b/lib/dml/moodle_transaction.php @@ -95,10 +95,10 @@ class moodle_transaction { /** * Rollback all current delegated transactions. * - * @param Exception $e mandatory exception + * @param $e mandatory exception/throwable * @return void */ - public function rollback(Exception $e) { + public function rollback($e) { if ($this->is_disposed()) { throw new dml_transaction_exception('Transactions already disposed', $this); } diff --git a/lib/phpunit/classes/advanced_testcase.php b/lib/phpunit/classes/advanced_testcase.php index dc52be9eaf5..410cc05ca5b 100644 --- a/lib/phpunit/classes/advanced_testcase.php +++ b/lib/phpunit/classes/advanced_testcase.php @@ -88,7 +88,13 @@ abstract class advanced_testcase extends base_testcase { trigger_error('Unexpected debugging() call detected.', E_USER_NOTICE); } - } catch (Exception $e) { + } catch (Exception $ex) { + $e = $ex; + } catch (Throwable $ex) { + $e = $ex; // PHP7. + } + + if (isset($e)) { // cleanup after failed expectation self::resetAllData(); throw $e; diff --git a/lib/phpunit/classes/basic_testcase.php b/lib/phpunit/classes/basic_testcase.php index 8e53d15afec..84f8506630e 100644 --- a/lib/phpunit/classes/basic_testcase.php +++ b/lib/phpunit/classes/basic_testcase.php @@ -62,7 +62,14 @@ abstract class basic_testcase extends base_testcase { try { parent::runBare(); - } catch (Exception $e) { + + } catch (Exception $ex) { + $e = $ex; + } catch (Throwable $ex) { + $e = $ex; // PHP7. + } + + if (isset($e)) { // cleanup after failed expectation phpunit_util::reset_all_data(); throw $e; diff --git a/lib/phpunit/classes/database_driver_testcase.php b/lib/phpunit/classes/database_driver_testcase.php index eaacaa253bc..14293b26657 100644 --- a/lib/phpunit/classes/database_driver_testcase.php +++ b/lib/phpunit/classes/database_driver_testcase.php @@ -142,7 +142,13 @@ abstract class database_driver_testcase extends base_testcase { try { parent::runBare(); - } catch (Exception $e) { + } catch (Exception $ex) { + $e = $ex; + } catch (Throwable $ex) { + $e = $ex; // PHP7. + } + + if (isset($e)) { if ($this->tdb->is_transaction_started()) { $this->tdb->force_transaction_rollback(); } diff --git a/lib/setuplib.php b/lib/setuplib.php index 145c4a47fa1..ce4dc325474 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -378,7 +378,13 @@ function default_exception_handler($ex) { $DB->set_debug(0); } echo $OUTPUT->fatal_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo); - } catch (Exception $out_ex) { + } catch (Exception $e) { + $out_ex = $e; + } catch (Throwable $e) { + $out_ex = $e; // PHP7. + } + + if (isset($out_ex)) { // default exception handler MUST not throw any exceptions!! // the problem here is we do not know if page already started or not, we only know that somebody messed up in outputlib or theme // so we just print at least something instead of "Exception thrown without a stack frame in Unknown on line 0":-(