Skip to content

Commit

Permalink
Allow to output more verbose error messages in the contao:resize-imag…
Browse files Browse the repository at this point in the history
…es command (see #866)

Description
-----------

Together with @Toflar we had a hard time debugging why the `contao:resize-images` command stopped at some point and did not want to continue. The error message was quite unclear especially that the requested file existed:

```
6/77b26349-9084f1ba.jpg......... failed
Unable to open image /var/www/vhosts/domain.tld/httpdocs/releases/233/assets/images/../../var/pim-images/77b26349.jpg
```

So we decided to introduce an option that allows to output more verbose error message simply by executing command in verbose mode `contao:resize-images -v`:

```
f/8ac5c4ec-213df40b.jpg.............. failed

 [ERROR] ImagickException: cache resources exhausted
         `/var/www/vhosts/domain.tld/httpdocs/releases/233/assets/images/../../var/pim-images/8ac5c4ec.jpg' @
         error/cache.c/OpenPixelCache/3864 in
         /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/imagine/imagine/src/Imagick/Imagine.php:69
         Stack trace:
         #0 /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/imagine/imagine/src/Imagick/Imagine.php(69):
         Imagick->__construct('/var/www/vhosts...')
         #1 /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/contao/image/src/Resizer.php(93):
         Imagine\Imagick\Imagine->open('/var/www/vhosts...')
         #2 /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/contao/image/src/DeferredResizer.php(185):
         Contao\Image\Resizer->executeResize(Object(Contao\Image\Image), Object(Contao\Image\ResizeCoordinates),
         '/var/www/vhosts...', Object(Contao\Image\ResizeOptions))
         #3 /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/contao/image/src/DeferredResizer.php(108):
         Contao\Image\DeferredResizer->executeDeferredResize('f/8ac5c4ec-213d...', Array,
         Object(Imagine\Imagick\Imagine))
         #4
         /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/contao/core-bundle/src/Command/ResizeImagesComma
         nd.php(189): Contao\Image\DeferredResizer->resizeDeferredImage(Object(Contao\Image\DeferredImage), false)
         #5
         /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/contao/core-bundle/src/Command/ResizeImagesComma
         nd.php(166): Contao\CoreBundle\Command\ResizeImagesCommand->resizeImage('f/8ac5c4ec-213d...',
         Object(Symfony\Component\Console\Style\SymfonyStyle))
         #6 /var/www/vhosts/domain.tld/httpdocs/releases/233/vendor/symfony/console/Command/Command.php(255):
```

Commits
-------

e9c6de9 Allow to output more verbose error messages in contao:resize-images command
  • Loading branch information
qzminski authored and leofeyer committed Nov 1, 2019
1 parent 4f214cf commit 69b1f3b
Showing 1 changed file with 26 additions and 17 deletions.
43 changes: 26 additions & 17 deletions core-bundle/src/Command/ResizeImagesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Terminal;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;
Expand Down Expand Up @@ -116,8 +118,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
throw new InvalidArgumentException(sprintf('Concurrent value "%s" is invalid.', $concurrent));
}

$io = new SymfonyStyle($input, $output);

if ($concurrent > 1) {
return $this->executeConcurrent($concurrent, $input, $output);
return $this->executeConcurrent($concurrent, $io);
}

$startTime = microtime(true);
Expand All @@ -129,30 +133,30 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$sleep = (1 - $throttle) / $throttle * $lastDuration;

if ($timeLimit && microtime(true) - $startTime + $maxDuration + $sleep > $timeLimit) {
$output->writeln("\n".'Time limit of '.$timeLimit.' seconds reached.');
$io->writeln("\n".'Time limit of '.$timeLimit.' seconds reached.');

return 0;
}

usleep((int) ($sleep * 1000000));

$maxDuration = max($maxDuration, $lastDuration = $this->resizeImage($path, $output));
$maxDuration = max($maxDuration, $lastDuration = $this->resizeImage($path, $io));
}

$output->writeln("\n".'All images resized.');
$io->writeln("\n".'All images resized.');

return 0;
}

private function resizeImage(string $path, OutputInterface $output): float
private function resizeImage(string $path, SymfonyStyle $io): float
{
$startTime = microtime(true);

if ($this->filesystem->exists($path)) {
return 0;
}

$output->write(str_pad($path, $this->terminalWidth + \strlen($path) - mb_strlen($path, 'UTF-8') - 13, '.').' ');
$io->write(str_pad($path, $this->terminalWidth + \strlen($path) - mb_strlen($path, 'UTF-8') - 13, '.').' ');

try {
$image = $this->imageFactory->create($this->targetDir.'/'.$path);
Expand All @@ -163,29 +167,34 @@ private function resizeImage(string $path, OutputInterface $output): float

if (null === $resizedImage) {
// Clear the current output line
$output->write("\r".str_repeat(' ', $this->terminalWidth)."\r");
$io->write("\r".str_repeat(' ', $this->terminalWidth)."\r");
} else {
$output->writeln(sprintf('done%7.3Fs', $duration = microtime(true) - $startTime));
$io->writeln(sprintf('done%7.3Fs', $duration = microtime(true) - $startTime));

return $duration;
}
} else {
// Clear the current output line
$output->write("\r".str_repeat(' ', $this->terminalWidth)."\r");
$io->write("\r".str_repeat(' ', $this->terminalWidth)."\r");
}
} catch (\Throwable $exception) {
$output->writeln('failed');
$output->writeln($exception->getMessage());
$io->writeln('failed');

if ($io->isVerbose()) {
$io->error(FlattenException::createFromThrowable($exception)->getAsString());
} else {
$io->writeln($exception->getMessage());
}
}

return 0;
}

private function executeConcurrent(int $count, InputInterface $input, OutputInterface $output): int
private function executeConcurrent(int $count, SymfonyStyle $io): int
{
$phpFinder = new PhpExecutableFinder();

$output->writeln('Starting '.$count.' concurrent processes...');
$io->writeln('Starting '.$count.' concurrent processes...');

if (false === ($phpPath = $phpFinder->find())) {
throw new \RuntimeException('The php executable could not be found.');
Expand All @@ -201,7 +210,7 @@ private function executeConcurrent(int $count, InputInterface $input, OutputInte
$process = new Process(array_merge(
[$phpPath],
$_SERVER['argv'],
['--concurrent=1', $output->isDecorated() ? '--ansi' : '--no-ansi']
['--concurrent=1', $io->isDecorated() ? '--ansi' : '--no-ansi']
));

$process->setTimeout(null);
Expand Down Expand Up @@ -230,7 +239,7 @@ private function executeConcurrent(int $count, InputInterface $input, OutputInte
$buffers[$index] = array_pop($rows);

// Write remaining rows to the output with thread prefix
$output->write(array_map(
$io->write(array_map(
static function ($row) use ($index) {
return sprintf('%02d: ', $index + 1).preg_replace('/^.*\r/s', '', $row)."\n";
},
Expand All @@ -241,9 +250,9 @@ static function ($row) use ($index) {
usleep(15000);
} while ($isRunning);

$output->write($buffers);
$io->write($buffers);

$output->write(array_map(
$io->write(array_map(
static function (Process $process): string {
return $process->getErrorOutput();
},
Expand Down

0 comments on commit 69b1f3b

Please sign in to comment.