Skip to content

Commit fc07627

Browse files
authored
Merge pull request #37944 from nextcloud/enh/allow-filescan-to-continue-on-error
Do not stop at the first PHP error/warning in files:scan
2 parents 185fe53 + 88405d3 commit fc07627

1 file changed

Lines changed: 33 additions & 36 deletions

File tree

apps/files/lib/Command/Scan.php

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Scan extends Base {
5858
protected float $execTime = 0;
5959
protected int $foldersCounter = 0;
6060
protected int $filesCounter = 0;
61+
protected int $errorsCounter = 0;
6162
private IRootFolder $root;
6263
private MetadataManager $metadataManager;
6364

@@ -148,10 +149,12 @@ protected function scanFiles(string $user, string $path, bool $scanMetadata, Out
148149

149150
$scanner->listen('\OC\Files\Utils\Scanner', 'StorageNotAvailable', function (StorageNotAvailableException $e) use ($output) {
150151
$output->writeln('Error while scanning, storage not available (' . $e->getMessage() . ')', OutputInterface::VERBOSITY_VERBOSE);
152+
++$this->errorsCounter;
151153
});
152154

153155
$scanner->listen('\OC\Files\Utils\Scanner', 'normalizedNameMismatch', function ($fullPath) use ($output) {
154156
$output->writeln("\t<error>Entry \"" . $fullPath . '" will not be accessible due to incompatible encoding</error>');
157+
++$this->errorsCounter;
155158
});
156159

157160
try {
@@ -164,14 +167,17 @@ protected function scanFiles(string $user, string $path, bool $scanMetadata, Out
164167
$output->writeln("<error>Home storage for user $user not writable or 'files' subdirectory missing</error>");
165168
$output->writeln(' ' . $e->getMessage());
166169
$output->writeln('Make sure you\'re running the scan command only as the user the web server runs as');
170+
++$this->errorsCounter;
167171
} catch (InterruptedException $e) {
168172
# exit the function if ctrl-c has been pressed
169173
$output->writeln('Interrupted by user');
170174
} catch (NotFoundException $e) {
171175
$output->writeln('<error>Path not found: ' . $e->getMessage() . '</error>');
176+
++$this->errorsCounter;
172177
} catch (\Exception $e) {
173178
$output->writeln('<error>Exception during scan: ' . $e->getMessage() . '</error>');
174179
$output->writeln('<error>' . $e->getTraceAsString() . '</error>');
180+
++$this->errorsCounter;
175181
}
176182
}
177183

@@ -192,19 +198,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
192198
$users = $input->getArgument('user_id');
193199
}
194200

195-
# restrict the verbosity level to VERBOSITY_VERBOSE
196-
if ($output->getVerbosity() > OutputInterface::VERBOSITY_VERBOSE) {
197-
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
198-
}
199-
200201
# check quantity of users to be process and show it on the command line
201202
$users_total = count($users);
202203
if ($users_total === 0) {
203204
$output->writeln('<error>Please specify the user id to scan, --all to scan for all users or --path=...</error>');
204205
return 1;
205206
}
206207

207-
$this->initTools();
208+
$this->initTools($output);
208209

209210
$user_count = 0;
210211
foreach ($users as $user) {
@@ -236,31 +237,37 @@ protected function execute(InputInterface $input, OutputInterface $output): int
236237
/**
237238
* Initialises some useful tools for the Command
238239
*/
239-
protected function initTools() {
240+
protected function initTools(OutputInterface $output) {
240241
// Start the timer
241242
$this->execTime = -microtime(true);
242243
// Convert PHP errors to exceptions
243-
set_error_handler([$this, 'exceptionErrorHandler'], E_ALL);
244+
set_error_handler(
245+
fn (int $severity, string $message, string $file, int $line): bool =>
246+
$this->exceptionErrorHandler($output, $severity, $message, $file, $line),
247+
E_ALL
248+
);
244249
}
245250

246251
/**
247-
* Processes PHP errors as exceptions in order to be able to keep track of problems
252+
* Processes PHP errors in order to be able to show them in the output
248253
*
249254
* @see https://www.php.net/manual/en/function.set-error-handler.php
250255
*
251256
* @param int $severity the level of the error raised
252257
* @param string $message
253258
* @param string $file the filename that the error was raised in
254259
* @param int $line the line number the error was raised
255-
*
256-
* @throws \ErrorException
257260
*/
258-
public function exceptionErrorHandler($severity, $message, $file, $line) {
259-
if (!(error_reporting() & $severity)) {
260-
// This error code is not included in error_reporting
261-
return;
261+
public function exceptionErrorHandler(OutputInterface $output, int $severity, string $message, string $file, int $line): bool {
262+
if (($severity === E_DEPRECATED) || ($severity === E_USER_DEPRECATED)) {
263+
// Do not show deprecation warnings
264+
return false;
262265
}
263-
throw new \ErrorException($message, 0, $severity, $file, $line);
266+
$e = new \ErrorException($message, 0, $severity, $file, $line);
267+
$output->writeln('<error>Error during scan: ' . $e->getMessage() . '</error>');
268+
$output->writeln('<error>' . $e->getTraceAsString() . '</error>', OutputInterface::VERBOSITY_VERY_VERBOSE);
269+
++$this->errorsCounter;
270+
return true;
264271
}
265272

266273
/**
@@ -271,28 +278,18 @@ protected function presentStats(OutputInterface $output) {
271278
$this->execTime += microtime(true);
272279

273280
$headers = [
274-
'Folders', 'Files', 'Elapsed time'
281+
'Folders',
282+
'Files',
283+
'Errors',
284+
'Elapsed time',
275285
];
276-
277-
$this->showSummary($headers, null, $output);
278-
}
279-
280-
/**
281-
* Shows a summary of operations
282-
*
283-
* @param string[] $headers
284-
* @param string[] $rows
285-
* @param OutputInterface $output
286-
*/
287-
protected function showSummary($headers, $rows, OutputInterface $output) {
288286
$niceDate = $this->formatExecTime();
289-
if (!$rows) {
290-
$rows = [
291-
$this->foldersCounter,
292-
$this->filesCounter,
293-
$niceDate,
294-
];
295-
}
287+
$rows = [
288+
$this->foldersCounter,
289+
$this->filesCounter,
290+
$this->errorsCounter,
291+
$niceDate,
292+
];
296293
$table = new Table($output);
297294
$table
298295
->setHeaders($headers)

0 commit comments

Comments
 (0)