- Moved the description for the specific storage exception first

- Introduced exceptions for try to get invalid storage
- ReferenceStorageException now extends StorageException
This commit is contained in:
Philipp Holzer 2021-08-10 21:30:40 +02:00
parent 813db7956f
commit 57438afbb3
No known key found for this signature in database
GPG key ID: 9A28B7D4FF5667BD
4 changed files with 42 additions and 31 deletions

View file

@ -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.

View file

@ -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));
}
}

View file

@ -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
{

View file

@ -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
{
}