Merge pull request #381 from acelaya/feature/update-db-errors

Feature/update db errors
This commit is contained in:
Alejandro Celaya 2019-03-16 11:25:32 +01:00 committed by GitHub
commit 781c6e94a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 10 deletions

View file

@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
#### Added #### Added
* [#153](https://github.com/shlinkio/shlink/issues/153) Updated to [doctrine/migrations](https://github.com/doctrine/migrations) version 2.0.0 * [#153](https://github.com/shlinkio/shlink/issues/153) Updated to [doctrine/migrations](https://github.com/doctrine/migrations) version 2.0.0
* [#376](https://github.com/shlinkio/shlink/issues/376) Allowed `visit:update-db` command to not return an error exit code even if download fails, by passing the `-i` flag.
#### Changed #### Changed

View file

@ -55,7 +55,7 @@
"filp/whoops": "^2.0", "filp/whoops": "^2.0",
"infection/infection": "^0.12.2", "infection/infection": "^0.12.2",
"phpstan/phpstan": "^0.11.2", "phpstan/phpstan": "^0.11.2",
"phpunit/phpcov": "^6.0@dev || ^5.0", "phpunit/phpcov": "^6.0 || ^5.0",
"phpunit/phpunit": "^8.0 || ^7.5", "phpunit/phpunit": "^8.0 || ^7.5",
"roave/security-advisories": "dev-master", "roave/security-advisories": "dev-master",
"shlinkio/php-coding-standard": "~1.1.0", "shlinkio/php-coding-standard": "~1.1.0",

View file

@ -9,9 +9,12 @@ use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Style\SymfonyStyle;
use function sprintf;
class UpdateDbCommand extends Command class UpdateDbCommand extends Command
{ {
public const NAME = 'visit:update-db'; public const NAME = 'visit:update-db';
@ -33,6 +36,12 @@ class UpdateDbCommand extends Command
->setHelp( ->setHelp(
'The GeoLite2 database is updated first Tuesday every month, so this command should be ideally run ' 'The GeoLite2 database is updated first Tuesday every month, so this command should be ideally run '
. 'every first Wednesday' . 'every first Wednesday'
)
->addOption(
'ignoreErrors',
'i',
InputOption::VALUE_NONE,
'Makes the command success even iof the update fails.'
); );
} }
@ -49,19 +58,32 @@ class UpdateDbCommand extends Command
}); });
$progressBar->finish(); $progressBar->finish();
$io->writeln(''); $io->newLine();
$io->success('GeoLite2 database properly updated'); $io->success('GeoLite2 database properly updated');
return ExitCodes::EXIT_SUCCESS; return ExitCodes::EXIT_SUCCESS;
} catch (RuntimeException $e) { } catch (RuntimeException $e) {
$progressBar->finish(); $progressBar->finish();
$io->writeln(''); $io->newLine();
$io->error('An error occurred while updating GeoLite2 database'); return $this->handleError($e, $io, $input);
}
}
private function handleError(RuntimeException $e, SymfonyStyle $io, InputInterface $input): int
{
$ignoreErrors = $input->getOption('ignoreErrors');
$baseErrorMsg = 'An error occurred while updating GeoLite2 database';
if ($ignoreErrors) {
$io->warning(sprintf('%s, but it was ignored', $baseErrorMsg));
return ExitCodes::EXIT_SUCCESS;
}
$io->error($baseErrorMsg);
if ($io->isVerbose()) { if ($io->isVerbose()) {
$this->getApplication()->renderException($e, $output); $this->getApplication()->renderException($e, $io);
} }
return ExitCodes::EXIT_FAILURE; return ExitCodes::EXIT_FAILURE;
} }
}
} }

View file

@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase;
use Prophecy\Argument; use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Visit\UpdateDbCommand; use Shlinkio\Shlink\CLI\Command\Visit\UpdateDbCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Common\Exception\RuntimeException; use Shlinkio\Shlink\Common\Exception\RuntimeException;
use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface; use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface;
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
@ -31,27 +32,45 @@ class UpdateDbCommandTest extends TestCase
} }
/** @test */ /** @test */
public function successMessageIsPrintedIfEverythingWorks() public function successMessageIsPrintedIfEverythingWorks(): void
{ {
$download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->will(function () { $download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->will(function () {
}); });
$this->commandTester->execute([]); $this->commandTester->execute([]);
$output = $this->commandTester->getDisplay(); $output = $this->commandTester->getDisplay();
$exitCode = $this->commandTester->getStatusCode();
$this->assertStringContainsString('GeoLite2 database properly updated', $output); $this->assertStringContainsString('GeoLite2 database properly updated', $output);
$this->assertEquals(ExitCodes::EXIT_SUCCESS, $exitCode);
$download->shouldHaveBeenCalledOnce(); $download->shouldHaveBeenCalledOnce();
} }
/** @test */ /** @test */
public function errorMessageIsPrintedIfAnExceptionIsThrown() public function errorMessageIsPrintedIfAnExceptionIsThrown(): void
{ {
$download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->willThrow(RuntimeException::class); $download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->willThrow(RuntimeException::class);
$this->commandTester->execute([]); $this->commandTester->execute([]);
$output = $this->commandTester->getDisplay(); $output = $this->commandTester->getDisplay();
$exitCode = $this->commandTester->getStatusCode();
$this->assertStringContainsString('An error occurred while updating GeoLite2 database', $output); $this->assertStringContainsString('An error occurred while updating GeoLite2 database', $output);
$this->assertEquals(ExitCodes::EXIT_FAILURE, $exitCode);
$download->shouldHaveBeenCalledOnce();
}
/** @test */
public function warningMessageIsPrintedIfAnExceptionIsThrownAndErrorsAreIgnored(): void
{
$download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->willThrow(RuntimeException::class);
$this->commandTester->execute(['--ignoreErrors' => true]);
$output = $this->commandTester->getDisplay();
$exitCode = $this->commandTester->getStatusCode();
$this->assertStringContainsString('ignored', $output);
$this->assertEquals(ExitCodes::EXIT_SUCCESS, $exitCode);
$download->shouldHaveBeenCalledOnce(); $download->shouldHaveBeenCalledOnce();
} }
} }