MDL-52284 core: compatibility with Exception/Throwable changes in PHP7
authorTony Levi <tony.levi@netspot.com.au>
Mon, 3 Aug 2015 06:46:03 +0000 (16:16 +0930)
committerMarina Glancy <marina@moodle.com>
Thu, 10 Dec 2015 02:49:36 +0000 (10:49 +0800)
backup/util/settings/tests/settings_test.php
lib/dml/moodle_database.php
lib/dml/moodle_transaction.php
lib/phpunit/classes/advanced_testcase.php
lib/phpunit/classes/basic_testcase.php
lib/phpunit/classes/database_driver_testcase.php
lib/setuplib.php

index 201d29e..a50023c 100644 (file)
@@ -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();
 
index fee0eca..78b11df 100644 (file)
@@ -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);
         }
index 106ffb8..a948441 100644 (file)
@@ -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);
         }
index dc52be9..410cc05 100644 (file)
@@ -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;
index 8e53d15..84f8506 100644 (file)
@@ -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;
index eaacaa2..14293b2 100644 (file)
@@ -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();
             }
index 145c4a4..ce4dc32 100644 (file)
@@ -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":-(