CRM_Core_Error::formatFooException - Don't bomb on 'Error'
authorTim Otten <totten@civicrm.org>
Tue, 3 Nov 2020 05:54:45 +0000 (21:54 -0800)
committerTim Otten <totten@civicrm.org>
Tue, 3 Nov 2020 06:06:18 +0000 (22:06 -0800)
PHP 7 updated the class hierarchy for exceptions. The top-level types for exceptions are now:

* class Throwable
* class Error extends Throwable
* class Exception extends Throwable

This patch fixes a problem when logging `Error`s, as in

```php
Civi::log()->warning('There was a problem', [
  'exception' => $e
]);
```

Before
------

If `$e` is an `Error`, it fails to log.

After
-----

It works whether `$e` is an `Error` or `Exception`.

See also: https://www.php.net/manual/en/language.errors.php7.php

CRM/Core/Error.php
tests/phpunit/CRM/Core/ErrorTest.php

index 6b264a944efed8b884bbce210a371902a7a0d8c8..4011b3e0afa3f0b6088d8d90fb6bf3be86d70d33 100644 (file)
@@ -817,11 +817,11 @@ class CRM_Core_Error extends PEAR_ErrorStack {
   /**
    * Render an exception as HTML string.
    *
-   * @param Exception $e
+   * @param Throwable $e
    * @return string
    *   printable HTML text
    */
-  public static function formatHtmlException(Exception $e) {
+  public static function formatHtmlException(Throwable $e) {
     $msg = '';
 
     // Exception metadata
@@ -856,11 +856,11 @@ class CRM_Core_Error extends PEAR_ErrorStack {
   /**
    * Write details of an exception to the log.
    *
-   * @param Exception $e
+   * @param Throwable $e
    * @return string
    *   printable plain text
    */
-  public static function formatTextException(Exception $e) {
+  public static function formatTextException(Throwable $e) {
     $msg = get_class($e) . ": \"" . $e->getMessage() . "\"\n";
 
     $ei = $e;
index c8f21a3171c6988add5b4c48ec965dfccab078bb..94ecc5f96f4e52fc1bea932e9872dc839939304d 100644 (file)
@@ -46,6 +46,18 @@ class CRM_Core_ErrorTest extends CiviUnitTestCase {
     $this->assertRegexp('/CRM_Core_ErrorTest->testFormatBacktrace_exception/', $msg);
   }
 
+  public function testExceptionLogging() {
+    $e = new \Exception("the exception");
+    Civi::log()->notice('There was an exception!', [
+      'exception' => $e,
+    ]);
+
+    $e = new Error('the error');
+    Civi::log()->notice('There was an error!', [
+      'exception' => $e,
+    ]);
+  }
+
   /**
    * We have two coding conventions for writing to log. Make sure that they work together.
    *