From 9750adacdd6095d96bb202bab0af608fbf63ad9c Mon Sep 17 00:00:00 2001 From: Bryan Davis Date: Thu, 11 Feb 2016 09:55:37 -0700 Subject: [PATCH] SessionProvider::mergeMetadata: Log additional data Add the data values and types to the exception raised when mismatched session data is processed. This is done by passing the old and new values on via a new MetadataMergeException class. The attached data is added to the debug logging context info when caught. Change-Id: If8a7174399289bc284ca1b36052ba515c8857c50 --- autoload.php | 1 + includes/session/MetadataMergeException.php | 70 +++++++++++++++++++ includes/session/SessionManager.php | 5 +- includes/session/SessionProvider.php | 9 ++- .../includes/session/SessionManagerTest.php | 2 +- .../includes/session/SessionProviderTest.php | 4 +- 6 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 includes/session/MetadataMergeException.php diff --git a/autoload.php b/autoload.php index d6e40777ff..ab6c5e0b80 100644 --- a/autoload.php +++ b/autoload.php @@ -796,6 +796,7 @@ $wgAutoloadLocalClasses = array( 'MediaWiki\\Session\\BotPasswordSessionProvider' => __DIR__ . '/includes/session/BotPasswordSessionProvider.php', 'MediaWiki\\Session\\CookieSessionProvider' => __DIR__ . '/includes/session/CookieSessionProvider.php', 'MediaWiki\\Session\\ImmutableSessionProviderWithCookie' => __DIR__ . '/includes/session/ImmutableSessionProviderWithCookie.php', + 'MediaWiki\\Session\\MetadataMergeException' => __DIR__ . '/includes/session/MetadataMergeException.php', 'MediaWiki\\Session\\PHPSessionHandler' => __DIR__ . '/includes/session/PHPSessionHandler.php', 'MediaWiki\\Session\\Session' => __DIR__ . '/includes/session/Session.php', 'MediaWiki\\Session\\SessionBackend' => __DIR__ . '/includes/session/SessionBackend.php', diff --git a/includes/session/MetadataMergeException.php b/includes/session/MetadataMergeException.php new file mode 100644 index 0000000000..9f42c278bc --- /dev/null +++ b/includes/session/MetadataMergeException.php @@ -0,0 +1,70 @@ + + * @copyright © 2016 Bryan Davis and Wikimedia Foundation. + * @since 1.27 + */ +class MetadataMergeException extends UnexpectedValueException { + /** @var array $context */ + protected $context; + + /** + * @param string $message + * @param int $code + * @param Exception|null $previous + * @param array $context Additional context data + */ + public function __construct( + $message = '', + $code = 0, + Exception $previous = null, + array $context = [] + ) { + parent::__construct( $message, $code, $previous ); + $this->context = $context; + } + + /** + * Get context data. + * @return array + */ + public function getContext() { + return $this->context; + } + + /** + * Set context data. + * @param array $context + */ + public function setContext( array $context ) { + $this->context = $context; + } +} diff --git a/includes/session/SessionManager.php b/includes/session/SessionManager.php index 83c30aba3b..6e4f99c0e7 100644 --- a/includes/session/SessionManager.php +++ b/includes/session/SessionManager.php @@ -744,13 +744,14 @@ final class SessionManager implements SessionManagerInterface { if ( $newProviderMetadata !== $providerMetadata ) { $newParams['metadata'] = $newProviderMetadata; } - } catch ( \UnexpectedValueException $ex ) { + } catch ( MetadataMergeException $ex ) { $this->logger->warning( 'Session "{session}": Metadata merge failed: {exception}', array( 'session' => $info, 'exception' => $ex, - ) ); + ) + $ex->getContext() + ); return false; } } diff --git a/includes/session/SessionProvider.php b/includes/session/SessionProvider.php index 0fd3a7197f..db6294ddd0 100644 --- a/includes/session/SessionProvider.php +++ b/includes/session/SessionProvider.php @@ -186,12 +186,17 @@ abstract class SessionProvider implements SessionProviderInterface, LoggerAwareI * @param array $savedMetadata Saved provider metadata * @param array $providedMetadata Provided provider metadata * @return array Resulting metadata - * @throws \UnexpectedValueException If the metadata cannot be merged + * @throws MetadataMergeException If the metadata cannot be merged */ public function mergeMetadata( array $savedMetadata, array $providedMetadata ) { foreach ( $providedMetadata as $k => $v ) { if ( array_key_exists( $k, $savedMetadata ) && $savedMetadata[$k] !== $v ) { - throw new \UnexpectedValueException( "Key \"$k\" changed" ); + $e = new MetadataMergeException( "Key \"$k\" changed" ); + $e->setContext( [ + 'old_value' => $savedMetadata[$k], + 'new_value' => $v, + ] ); + throw $e; } } return $providedMetadata; diff --git a/tests/phpunit/includes/session/SessionManagerTest.php b/tests/phpunit/includes/session/SessionManagerTest.php index 16beb7299e..94bf1844da 100644 --- a/tests/phpunit/includes/session/SessionManagerTest.php +++ b/tests/phpunit/includes/session/SessionManagerTest.php @@ -1112,7 +1112,7 @@ class SessionManagerTest extends MediaWikiTestCase { $provider->expects( $this->any() )->method( 'mergeMetadata' ) ->will( $this->returnCallback( function ( $a, $b ) { if ( $b === array( 'Throw' ) ) { - throw new \UnexpectedValueException( 'no merge!' ); + throw new MetadataMergeException( 'no merge!' ); } return array( 'Merged' ); } ) ); diff --git a/tests/phpunit/includes/session/SessionProviderTest.php b/tests/phpunit/includes/session/SessionProviderTest.php index d7aebcd6b3..7d9004a7a0 100644 --- a/tests/phpunit/includes/session/SessionProviderTest.php +++ b/tests/phpunit/includes/session/SessionProviderTest.php @@ -89,8 +89,10 @@ class SessionProviderTest extends MediaWikiTestCase { array( 'bar' => 2, 'baz' => '3' ) ); $this->fail( 'Expected exception not thrown' ); - } catch ( \UnexpectedValueException $ex ) { + } catch ( MetadataMergeException $ex ) { $this->assertSame( 'Key "baz" changed', $ex->getMessage() ); + $this->assertSame( + [ 'old_value' => 3, 'new_value' => '3' ], $ex->getContext() ); } $res = $provider->mergeMetadata( -- 2.20.1