From 73f8b99ec74d3ebbb196540a6115584e72f9a640 Mon Sep 17 00:00:00 2001 From: Ryan Jacobs <rjacobs@422459.no-reply.drupal.org> Date: Fri, 24 Feb 2017 17:18:09 -0600 Subject: [PATCH] Issue #2774313 by rjacobs, tstoeckler: More gracefully deal with library-specific errors at runtime. Squashed commit of the following: commit cbd3b2f37baebd02b33648e92c31e59376d80e22 Author: Ryan Jacobs <rjacobs@422459.no-reply.drupal.org> Date: Thu Feb 2 21:47:51 2017 -0600 Issue #2774313: Add exception handling to libraries_library_info_build(). commit 6f4f6a5f85d0bee12d474ab147fc2c9d7d1e49a1 Author: Ryan Jacobs <rjacobs@422459.no-reply.drupal.org> Date: Mon Jan 30 22:30:53 2017 -0600 Issue #2774313: Skip local version detection for uninstalled local library. --- libraries.module | 33 ++++++++++++++++--- .../InvalidLibraryDependencyException.php | 3 +- .../LibraryDefinitionNotFoundException.php | 3 +- .../LibraryNotInstalledException.php | 3 +- .../LibraryTypeNotFoundException.php | 3 +- .../UnknownLibraryVersionException.php | 3 +- .../Remote/RemoteLibraryTrait.php | 2 +- src/ExternalLibrary/Type/LibraryTypeBase.php | 7 ++-- .../Utility/LibraryAccessorInterface.php | 18 ++++++++++ .../Utility/LibraryIdAccessorInterface.php | 18 ++++++++++ 10 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 src/ExternalLibrary/Utility/LibraryAccessorInterface.php create mode 100644 src/ExternalLibrary/Utility/LibraryIdAccessorInterface.php diff --git a/libraries.module b/libraries.module index 709e562..3006c34 100644 --- a/libraries.module +++ b/libraries.module @@ -8,23 +8,46 @@ use Drupal\Core\DrupalKernel; use Drupal\Core\Extension\ModuleHandler; use Drupal\libraries\ExternalLibrary\Asset\AttachableAssetLibraryRegistrationInterface; +use Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorInterface; +use Drupal\libraries\ExternalLibrary\Utility\LibraryIdAccessorInterface; use Symfony\Component\Yaml\Parser; /** * Implements hook_library_info_build(). + * + * Register external asset libraries with Drupal core's library APIs. */ function libraries_library_info_build() { /** @var \Drupal\libraries\ExternalLibrary\LibraryManagerInterface $library_manager */ $library_manager = \Drupal::service('libraries.manager'); - $attachable_libraries = []; + $libraries_with_errors = []; foreach ($library_manager->getRequiredLibraryIds() as $external_library_id) { - $external_library = $library_manager->getLibrary($external_library_id); - $library_type = $external_library->getType(); - if ($library_type instanceof AttachableAssetLibraryRegistrationInterface) { - $attachable_libraries += $library_type->getAttachableAssetLibraries($external_library, $library_manager); + try { + $external_library = $library_manager->getLibrary($external_library_id); + $library_type = $external_library->getType(); + if ($library_type instanceof AttachableAssetLibraryRegistrationInterface) { + $attachable_libraries += $library_type->getAttachableAssetLibraries($external_library, $library_manager); + } + } + catch (\Exception $e) { + // Library-specific exceptions should not be allowed to kill the rest of + // the build process, but should be logged. + if ($e instanceof LibraryIdAccessorInterface || $e instanceof LibraryAccessorInterface) { + $libraries_with_errors[] = $external_library_id; + watchdog_exception('libraries', $e); + } + else { + // Re-throw exceptions that are not library-specific. + throw $e; + } } } + // If we had library specific errors also log an informative message to + // tell admins that detection will not be run again without a cache clear. + if ($libraries_with_errors) { + \Drupal::logger('libraries')->error('The following external libraries could not successfully be registered with Drupal core: @libs. See earlier log entries for more details. Once these issues are addressed please be sure to clear your Drupal library cache to ensure external library detection is run again.', ['@libs' => implode(',', $libraries_with_errors)]); + } return $attachable_libraries; } diff --git a/src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php b/src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php index 9b741e1..7ab3eeb 100644 --- a/src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php +++ b/src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php @@ -5,11 +5,12 @@ namespace Drupal\libraries\ExternalLibrary\Exception; use Drupal\libraries\ExternalLibrary\Utility\DependencyAccessorTrait; use Drupal\libraries\ExternalLibrary\LibraryInterface; use Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorTrait; +use Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorInterface; /** * Provides an exception for an invalid library exception. */ -class InvalidLibraryDependencyException extends \UnexpectedValueException { +class InvalidLibraryDependencyException extends \UnexpectedValueException implements LibraryAccessorInterface { use LibraryAccessorTrait; use DependencyAccessorTrait; diff --git a/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php b/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php index 0e5e338..c274302 100644 --- a/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php +++ b/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php @@ -3,11 +3,12 @@ namespace Drupal\libraries\ExternalLibrary\Exception; use Drupal\libraries\ExternalLibrary\Utility\LibraryIdAccessorTrait; +use Drupal\libraries\ExternalLibrary\Utility\LibraryIdAccessorInterface; /** * Provides an exception for a library definition that cannot be found. */ -class LibraryDefinitionNotFoundException extends \RuntimeException { +class LibraryDefinitionNotFoundException extends \RuntimeException implements LibraryIdAccessorInterface { use LibraryIdAccessorTrait; diff --git a/src/ExternalLibrary/Exception/LibraryNotInstalledException.php b/src/ExternalLibrary/Exception/LibraryNotInstalledException.php index c65821f..ed48a62 100644 --- a/src/ExternalLibrary/Exception/LibraryNotInstalledException.php +++ b/src/ExternalLibrary/Exception/LibraryNotInstalledException.php @@ -4,11 +4,12 @@ namespace Drupal\libraries\ExternalLibrary\Exception; use Drupal\libraries\ExternalLibrary\Local\LocalLibraryInterface; use Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorTrait; +use Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorInterface; /** * Provides an exception for a library that is not installed. */ -class LibraryNotInstalledException extends \RuntimeException { +class LibraryNotInstalledException extends \RuntimeException implements LibraryAccessorInterface { use LibraryAccessorTrait; diff --git a/src/ExternalLibrary/Exception/LibraryTypeNotFoundException.php b/src/ExternalLibrary/Exception/LibraryTypeNotFoundException.php index 7531bf3..b5655bb 100644 --- a/src/ExternalLibrary/Exception/LibraryTypeNotFoundException.php +++ b/src/ExternalLibrary/Exception/LibraryTypeNotFoundException.php @@ -3,11 +3,12 @@ namespace Drupal\libraries\ExternalLibrary\Exception; use Drupal\libraries\ExternalLibrary\Utility\LibraryIdAccessorTrait; +use Drupal\libraries\ExternalLibrary\Utility\LibraryIdAccessorInterface; /** * Provides an exception for a library definition without a type declaration. */ -class LibraryTypeNotFoundException extends \RuntimeException { +class LibraryTypeNotFoundException extends \RuntimeException implements LibraryAccessorInterface { use LibraryIdAccessorTrait; diff --git a/src/ExternalLibrary/Exception/UnknownLibraryVersionException.php b/src/ExternalLibrary/Exception/UnknownLibraryVersionException.php index 72bd153..4afe059 100644 --- a/src/ExternalLibrary/Exception/UnknownLibraryVersionException.php +++ b/src/ExternalLibrary/Exception/UnknownLibraryVersionException.php @@ -3,12 +3,13 @@ namespace Drupal\libraries\ExternalLibrary\Exception; use Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorTrait; +use Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorInterface; use Drupal\libraries\ExternalLibrary\Version\VersionedLibraryInterface; /** * Provides an exception for libraries whose version has not been detected. */ -class UnknownLibraryVersionException extends \RuntimeException { +class UnknownLibraryVersionException extends \RuntimeException implements LibraryAccessorInterface { use LibraryAccessorTrait; diff --git a/src/ExternalLibrary/Remote/RemoteLibraryTrait.php b/src/ExternalLibrary/Remote/RemoteLibraryTrait.php index 0fb82c0..d55f3c2 100644 --- a/src/ExternalLibrary/Remote/RemoteLibraryTrait.php +++ b/src/ExternalLibrary/Remote/RemoteLibraryTrait.php @@ -26,7 +26,7 @@ trait RemoteLibraryTrait { * @see \Drupal\libraries\ExternalLibrary\Remote\RemoteLibraryInterface::hasRemoteUrl() */ public function hasRemoteUrl() { - return isset($this->remoteUrl); + return !empty($this->remoteUrl); } /** diff --git a/src/ExternalLibrary/Type/LibraryTypeBase.php b/src/ExternalLibrary/Type/LibraryTypeBase.php index 08cd61a..9774e97 100644 --- a/src/ExternalLibrary/Type/LibraryTypeBase.php +++ b/src/ExternalLibrary/Type/LibraryTypeBase.php @@ -74,9 +74,10 @@ abstract class LibraryTypeBase implements if (!$library->isInstalled()) { $this->locatorFactory->createInstance('global')->locate($library); } - } - if ($library instanceof VersionedLibraryInterface) { - $library->getVersionDetector($this->detectorFactory)->detectVersion($library); + // Also fetch version information. + if ($library->isInstalled() && $library instanceof VersionedLibraryInterface) { + $library->getVersionDetector($this->detectorFactory)->detectVersion($library); + } } } diff --git a/src/ExternalLibrary/Utility/LibraryAccessorInterface.php b/src/ExternalLibrary/Utility/LibraryAccessorInterface.php new file mode 100644 index 0000000..72b0093 --- /dev/null +++ b/src/ExternalLibrary/Utility/LibraryAccessorInterface.php @@ -0,0 +1,18 @@ +<?php + +namespace Drupal\libraries\ExternalLibrary\Utility; + +/** + * Provides an interface for classes giving access to a library. + */ +interface LibraryAccessorInterface { + + /** + * Returns the library. + * + * @return \Drupal\libraries\ExternalLibrary\LibraryInterface + * The library. + */ + public function getLibrary(); + +} diff --git a/src/ExternalLibrary/Utility/LibraryIdAccessorInterface.php b/src/ExternalLibrary/Utility/LibraryIdAccessorInterface.php new file mode 100644 index 0000000..98928e9 --- /dev/null +++ b/src/ExternalLibrary/Utility/LibraryIdAccessorInterface.php @@ -0,0 +1,18 @@ +<?php + +namespace Drupal\libraries\ExternalLibrary\Utility; + +/** + * Provides an interface for classes giving access to a library ID. + */ +interface LibraryAccessorIdInterface { + + /** + * Returns the ID of the library. + * + * @return string + * The library ID. + */ + public function getLibraryId(); + +} -- GitLab