mirror of
https://github.com/nextcloud/server.git
synced 2026-02-18 18:28:50 -05:00
fix: better error message when trying to scan a folder that is already being scanned
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
5f40fad790
commit
bb4cf2830a
5 changed files with 48 additions and 7 deletions
|
|
@ -24,6 +24,7 @@ use OCP\Files\NotFoundException;
|
|||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCP\FilesMetadata\IFilesMetadataManager;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Lock\LockedException;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
|
|
@ -165,6 +166,12 @@ class Scan extends Base {
|
|||
} catch (NotFoundException $e) {
|
||||
$output->writeln('<error>Path not found: ' . $e->getMessage() . '</error>');
|
||||
++$this->errorsCounter;
|
||||
} catch (LockedException $e) {
|
||||
if (str_starts_with($e->getPath(), 'scanner::')) {
|
||||
$output->writeln('<error>Another process is already scanning \'' . substr($e->getPath(), strlen('scanner::')) . '\'</error>');
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>Exception during scan: ' . $e->getMessage() . '</error>');
|
||||
$output->writeln('<error>' . $e->getTraceAsString() . '</error>');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace OCA\Files_External\Command;
|
|||
use OC\Files\Cache\Scanner;
|
||||
use OCA\Files_External\Service\GlobalStoragesService;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Lock\LockedException;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
|
@ -82,7 +83,19 @@ class Scan extends StorageAuthBase {
|
|||
$this->abortIfInterrupted();
|
||||
});
|
||||
|
||||
$scanner->scan($path);
|
||||
try {
|
||||
$scanner->scan($path);
|
||||
} catch (LockedException $e) {
|
||||
if (is_string($e->getReadablePath()) && str_starts_with($e->getReadablePath(), 'scanner::')) {
|
||||
if ($e->getReadablePath() === 'scanner::') {
|
||||
$output->writeln('<error>Another process is already scanning this storage</error>');
|
||||
} else {
|
||||
$output->writeln('<error>Another process is already scanning \'' . substr($e->getReadablePath(), strlen('scanner::')) . '\' in this storage</error>');
|
||||
}
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$this->presentStats($output);
|
||||
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ class Scanner extends BasicEmitter implements IScanner {
|
|||
* @var \OC\Files\Cache\CacheEntry $cacheData
|
||||
*/
|
||||
$newData = $this->array_diff_assoc_multi($data, $cacheData->getData());
|
||||
|
||||
|
||||
// make it known to the caller that etag has been changed and needs propagation
|
||||
if (isset($newData['etag'])) {
|
||||
$data['etag_changed'] = true;
|
||||
|
|
@ -351,23 +351,23 @@ class Scanner extends BasicEmitter implements IScanner {
|
|||
*
|
||||
*/
|
||||
protected function array_diff_assoc_multi(array $array1, array $array2) {
|
||||
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($array1 as $key => $value) {
|
||||
|
||||
|
||||
// if $array2 doesn't have the same key, that's a result
|
||||
if (!array_key_exists($key, $array2)) {
|
||||
$result[$key] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// if $array2's value for the same key is different, that's a result
|
||||
if ($array2[$key] !== $value && !is_array($value)) {
|
||||
$result[$key] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (is_array($value)) {
|
||||
$nestedDiff = $this->array_diff_assoc_multi($value, $array2[$key]);
|
||||
if (!empty($nestedDiff)) {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use OCP\Files\Storage\IStorage;
|
|||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Lock\ILockingProvider;
|
||||
use OCP\Lock\LockedException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -260,7 +261,15 @@ class Scanner extends PublicEmitter {
|
|||
try {
|
||||
$propagator = $storage->getPropagator();
|
||||
$propagator->beginBatch();
|
||||
$scanner->scan($relativePath, $recursive, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
|
||||
try {
|
||||
$scanner->scan($relativePath, $recursive, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
|
||||
} catch (LockedException $e) {
|
||||
if (is_string($e->getReadablePath()) && str_starts_with($e->getReadablePath(), 'scanner::')) {
|
||||
throw new LockedException("scanner::$dir", $e, $e->getExistingLock());
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
$cache = $storage->getCache();
|
||||
if ($cache instanceof Cache) {
|
||||
// only re-calculate for the root folder we scanned, anything below that is taken care of by the scanner
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ class LockedException extends \Exception {
|
|||
/** @var string|null */
|
||||
private $existingLock;
|
||||
|
||||
private ?string $readablePath;
|
||||
|
||||
/**
|
||||
* LockedException constructor.
|
||||
*
|
||||
|
|
@ -34,6 +36,7 @@ class LockedException extends \Exception {
|
|||
* @since 8.1.0
|
||||
*/
|
||||
public function __construct(string $path, ?\Exception $previous = null, ?string $existingLock = null, ?string $readablePath = null) {
|
||||
$this->readablePath = $readablePath;
|
||||
if ($readablePath) {
|
||||
$message = "\"$path\"(\"$readablePath\") is locked";
|
||||
} else {
|
||||
|
|
@ -62,4 +65,13 @@ class LockedException extends \Exception {
|
|||
public function getExistingLock(): ?string {
|
||||
return $this->existingLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?string
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function getReadablePath(): ?string {
|
||||
return $this->readablePath;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue