diff --git a/doc/AddonStorageBackend.md b/doc/AddonStorageBackend.md index 72e146779..b9b718247 100644 --- a/doc/AddonStorageBackend.md +++ b/doc/AddonStorageBackend.md @@ -122,6 +122,14 @@ abstract class StorageTest There are two intended types of exceptions for storages +### `ReferenceStorageExecption` + +This storage exception should be used in case the caller tries to use an invalid references. +This could happen in case the caller tries to delete or update an unknown reference. +The implementation of the storage backend must not ignore invalid references. + +Avoid throwing the common `StorageExecption` instead of the `ReferenceStorageException` at this particular situation! + ### `StorageException` This is the common exception in case unexpected errors happen using the storage backend. @@ -145,14 +153,6 @@ class ExampleStorage implements ISelectableStorage } ``` -### `ReferenceStorageExecption` - -This storage exception should be used in case the caller tries to use an invalid references. -This could happen in case the caller tries to delete or update an unknown reference. -The implementation of the storage backend must not ignore invalid references. - -Avoid throwing the common `StorageExecption` instead of the `ReferenceStorageException` at this particular situation! - ## Example Here an hypotetical addon which register a useless storage backend. diff --git a/src/Core/StorageManager.php b/src/Core/StorageManager.php index 03f89f312..4603b0fde 100644 --- a/src/Core/StorageManager.php +++ b/src/Core/StorageManager.php @@ -25,7 +25,7 @@ use Exception; use Friendica\Core\Config\IConfig; use Friendica\Database\Database; use Friendica\Model\Storage; -use Friendica\Network\IHTTPRequest; +use Friendica\Network\HTTPException\InternalServerErrorException; use Psr\Log\LoggerInterface; @@ -98,11 +98,12 @@ class StorageManager /** * Returns a selectable storage backend class by registered name * - * @param string|null $name Backend name + * @param string $name Backend name * - * @return Storage\ISelectableStorage|null null if no backend registered at $name + * @return Storage\ISelectableStorage * - * @throws \Friendica\Network\HTTPException\InternalServerErrorException + * @throws Storage\ReferenceStorageException in case there's no backend class for the name + * @throws Storage\StorageException in case of an unexpected failure during the hook call */ public function getSelectableStorageByName(string $name = null) { @@ -127,16 +128,20 @@ class StorageManager 'name' => $name, 'storage' => null, ]; - Hook::callAll('storage_instance', $data); - if (($data['storage'] ?? null) instanceof Storage\ISelectableStorage) { - $this->backendInstances[$data['name'] ?? $name] = $data['storage']; - } else { - return null; + try { + Hook::callAll('storage_instance', $data); + if (($data['storage'] ?? null) instanceof Storage\ISelectableStorage) { + $this->backendInstances[$data['name'] ?? $name] = $data['storage']; + } else { + throw new Storage\ReferenceStorageException(sprintf('Backend %s was not found', $name)); + } + } catch (InternalServerErrorException $exception) { + throw new Storage\StorageException(sprintf('Failed calling hook::storage_instance for backend %s', $name), $exception); } break; } } else { - return null; + throw new Storage\ReferenceStorageException(sprintf('Backend %s is not valid', $name)); } } @@ -146,13 +151,14 @@ class StorageManager /** * Return storage backend class by registered name * - * @param string|null $name Backend name + * @param string $name Backend name * - * @return Storage\IStorage|null null if no backend registered at $name + * @return Storage\IStorage * - * @throws \Friendica\Network\HTTPException\InternalServerErrorException + * @throws Storage\ReferenceStorageException in case there's no backend class for the name + * @throws Storage\StorageException in case of an unexpected failure during the hook call */ - public function getByName(string $name = null) + public function getByName(string $name) { // @todo 2020.09 Remove this call after 2 releases $name = $this->checkLegacyBackend($name); @@ -182,16 +188,20 @@ class StorageManager 'name' => $name, 'storage' => null, ]; - Hook::callAll('storage_instance', $data); - if (($data['storage'] ?? null) instanceof Storage\IStorage) { - $this->backendInstances[$data['name'] ?? $name] = $data['storage']; - } else { - return null; + try { + Hook::callAll('storage_instance', $data); + if (($data['storage'] ?? null) instanceof Storage\IStorage) { + $this->backendInstances[$data['name'] ?? $name] = $data['storage']; + } else { + throw new Storage\ReferenceStorageException(sprintf('Backend %s was not found', $name)); + } + } catch (InternalServerErrorException $exception) { + throw new Storage\StorageException(sprintf('Failed calling hook::storage_instance for backend %s', $name), $exception); } break; } } else { - return null; + throw new Storage\ReferenceStorageException(sprintf('Backend %s is not valid', $name)); } } diff --git a/src/Model/Storage/ISelectableStorage.php b/src/Model/Storage/ISelectableStorage.php index f1477a79c..d3b754777 100644 --- a/src/Model/Storage/ISelectableStorage.php +++ b/src/Model/Storage/ISelectableStorage.php @@ -23,6 +23,9 @@ namespace Friendica\Model\Storage; /** * Interface for selectable storage backends + * + * Used for storages with CRUD functionality, mainly used for user data (e.g. photos, attachements). + * There's only one active, selectable storage possible and can be selected by the current administrator */ interface ISelectableStorage extends IStorage { diff --git a/src/Model/Storage/ReferenceStorageException.php b/src/Model/Storage/ReferenceStorageException.php index c4de1f879..fcfd3ab59 100644 --- a/src/Model/Storage/ReferenceStorageException.php +++ b/src/Model/Storage/ReferenceStorageException.php @@ -21,11 +21,9 @@ namespace Friendica\Model\Storage; -use Exception; - /** * Storage Exception in case of invalid references */ -class ReferenceStorageException extends Exception +class ReferenceStorageException extends StorageException { }