EBernhardson has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/111936

Change subject: Catch catchable fatal errors when formatting echo notifications
......................................................................

Catch catchable fatal errors when formatting echo notifications

Change-Id: Ieaf02ece716802309e85ed0e32a0a15fcd24c50d
(cherry picked from commit fcd4f67c93695b763102367d10f866fb7be2984b)
---
M controller/NotificationController.php
M tests/NotificationFormatterTest.php
2 files changed, 35 insertions(+), 10 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Echo 
refs/changes/36/111936/1

diff --git a/controller/NotificationController.php 
b/controller/NotificationController.php
index 6d70231..638cb75 100644
--- a/controller/NotificationController.php
+++ b/controller/NotificationController.php
@@ -327,13 +327,15 @@
 
                $eventType = $event->getType();
 
+               $res = '';
                if ( isset( $wgEchoNotifications[$eventType] ) ) {
+                       set_error_handler( array( __CLASS__, 
'formatterErrorHandler' ), -1 );
                        try {
                                $params = $wgEchoNotifications[$eventType];
                                $notifier = EchoNotificationFormatter::factory( 
$params );
                                $notifier->setOutputFormat( $format );
 
-                               return $notifier->format( $event, $user, $type 
);
+                               $res = $notifier->format( $event, $user, $type 
);
                        } catch ( Exception $e ) {
                                $meta = array(
                                        'id' => $event->getId(),
@@ -344,11 +346,38 @@
                                );
                                wfDebugLog( __CLASS__, __FUNCTION__ . ": Error 
formatting " . FormatJson::encode( $meta ) );
                                MWExceptionHandler::logException( $e );
-                               return '';
                        }
+                       restore_error_handler();
                }
 
-               return Xml::tags( 'span', array( 'class' => 'error' ),
-                       wfMessage( 'echo-error-no-formatter', $event->getType() 
)->escaped() );
+               if ( $res ) {
+                       return $res;
+               } else {
+                       return Xml::tags( 'span', array( 'class' => 'error' ),
+                               wfMessage( 'echo-error-no-formatter', 
$event->getType() )->escaped() );
+               }
+       }
+
+       /**
+        * INTERNAL.  Must be public to be callable by the php error handling 
methods.
+        *
+        * Converts E_RECOVERABLE_ERROR, such as passing null to a method 
expecting 
+        * a non-null object, into exceptions.
+        */
+       public static function formatterErrorHandler( $errno, $errstr, 
$errfile, $errline ) {
+               if ( $errno !== E_RECOVERABLE_ERROR ) {
+                       return false;
+               }
+
+               throw new CatchableFatalErrorException( $errno, $errstr, 
$errfile, $errline );
+       }
+}
+
+class CatchableFatalErrorException extends MWException {
+       public function __construct( $errno, $errstr, $errfile, $errline ) {
+               parent::__construct( "Catchable fatal error: $errstr", $errno );
+               // inherited protected variables from \Exception
+               $this->file = $errfile;
+               $this->line = $errline;
        }
 }
diff --git a/tests/NotificationFormatterTest.php 
b/tests/NotificationFormatterTest.php
index 7c8b457..4e38252 100644
--- a/tests/NotificationFormatterTest.php
+++ b/tests/NotificationFormatterTest.php
@@ -206,19 +206,15 @@
                $this->assertContains( $expect, $this->format( $event, 'html' ) 
);
        }
 
-       protected function format( EchoEvent $event, $format, $user = false, 
$type = 'web', array $params = array() ) {
+       protected function format( EchoEvent $event, $format, $user = false, 
$type = 'web' ) {
                global $wgEchoNotifications;
-
-               $params += $wgEchoNotifications[ $event->getType() ];
-               $formatter = EchoNotificationFormatter::factory( $params );
-               $formatter->setOutputFormat( $format );
 
                if ( $user === false ) {
                        $user = 
User::newFromName('Notification-formatter-test');
                }
 
                // Notification users can not be anonymous, use a fake user id
-               return $formatter->format( $event, $user, $type );
+               return EchoNotificationController::formatNotification( $event, 
$user, $format, $type );
        }
 
        protected function mockEvent( $type, array $extra = array(), Revision 
$rev = null ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/111936
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ieaf02ece716802309e85ed0e32a0a15fcd24c50d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: wmf/1.23wmf12
Gerrit-Owner: EBernhardson <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to