Skip to content

Commit 5cd82df

Browse files
committed
Clean up API error handling with concise user messages
1 parent c3371b7 commit 5cd82df

File tree

8 files changed

+120
-32
lines changed

8 files changed

+120
-32
lines changed

Cli/Application.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727

2828
class Application extends SymfonyApplication
2929
{
30-
const APPLICATION_NAME = 'SymfonyInsight CLI';
31-
const APPLICATION_VERSION = '1.7.4';
30+
public const APPLICATION_NAME = 'SymfonyInsight CLI';
31+
32+
public const APPLICATION_VERSION = '1.7.4';
3233

3334
private $api;
3435
private $apiConfig;

Cli/Descriptor/PmdDescriptor.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77

88
class PmdDescriptor extends AbstractDescriptor
99
{
10-
const PHPMD_PRIORITY_HIGH = 1;
11-
const PHPMD_PRIORITY_MEDIUM_HIGH = 2;
12-
const PHPMD_PRIORITY_MEDIUM = 3;
13-
const PHPMD_PRIORITY_MEDIUM_LOW = 4;
14-
const PHPMD_PRIORITY_LOW = 5;
10+
public const PHPMD_PRIORITY_HIGH = 1;
11+
12+
public const PHPMD_PRIORITY_MEDIUM_HIGH = 2;
13+
14+
public const PHPMD_PRIORITY_MEDIUM = 3;
15+
16+
public const PHPMD_PRIORITY_MEDIUM_LOW = 4;
17+
18+
public const PHPMD_PRIORITY_LOW = 5;
1519

1620
protected function describeAnalysis(Analysis $analysis, array $options = [])
1721
{
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace SensioLabs\Insight\Cli\EventListener;
4+
5+
use SensioLabs\Insight\Sdk\Exception\ApiClientException;
6+
use SensioLabs\Insight\Sdk\Exception\ApiParserException;
7+
use SensioLabs\Insight\Sdk\Exception\ApiServerException;
8+
use Symfony\Component\Console\ConsoleEvents;
9+
use Symfony\Component\Console\Event\ConsoleErrorEvent;
10+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
11+
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
12+
13+
class ApiErrorListener implements EventSubscriberInterface
14+
{
15+
public static function getSubscribedEvents(): array
16+
{
17+
return [
18+
ConsoleEvents::ERROR => ['onConsoleError', 256],
19+
];
20+
}
21+
22+
public function onConsoleError(ConsoleErrorEvent $event): void
23+
{
24+
$output = $event->getOutput();
25+
$error = $event->getError();
26+
27+
if ($error instanceof ApiClientException) {
28+
$this->showClientError($error, $output);
29+
} elseif ($error instanceof ApiServerException) {
30+
$output->writeln('<error>Server temporarily unavailable. Please try again in a few minutes.</error>');
31+
} elseif ($error instanceof ApiParserException) {
32+
$output->writeln('<error>Unable to process server response. Please try again later.</error>');
33+
} elseif ($error instanceof TransportExceptionInterface) {
34+
$output->writeln('<error>Network connection failed. Check your internet connection.</error>');
35+
} else {
36+
$output->writeln('<error>Something went wrong. Please try again.</error>');
37+
}
38+
39+
$event->setExitCode(0);
40+
}
41+
42+
private function showClientError(ApiClientException $e, $output): void
43+
{
44+
$message = $e->getMessage();
45+
if (false !== strpos($message, '401') || false !== strpos($message, 'Unauthorized')) {
46+
$output->writeln('<error>Invalid API credentials. Run "php insight.phar configure" to set up your token.</error>');
47+
} elseif (false !== strpos($message, '404') || false !== strpos($message, 'Not Found')) {
48+
$output->writeln('<error>Project not found. Check the project UUID and try again.</error>');
49+
} elseif (false !== strpos($message, '403') || false !== strpos($message, 'Forbidden')) {
50+
$output->writeln('<error>Access denied. You don\'t have permission for this project.</error>');
51+
} else {
52+
$output->writeln('<error>Request failed. Please check your input and try again.</error>');
53+
}
54+
}
55+
}

Sdk/Api.php

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
class Api
3333
{
34-
const ENDPOINT = 'https://insight.symfony.com';
34+
public const ENDPOINT = 'https://insight.symfony.com';
3535

3636
private $baseUrl;
3737
private $httpClient;
@@ -265,7 +265,7 @@ private function send($method, $url, $body = null): string
265265
} catch (TransportExceptionInterface $e) {
266266
$this->logException($e);
267267

268-
throw new ApiServerException('Something went wrong with upstream', 0, $e);
268+
throw $e;
269269
} catch (ServerExceptionInterface $e) {
270270
$this->logException($e);
271271

@@ -289,12 +289,22 @@ private function processClientError(HttpExceptionInterface $e)
289289

290290
private function logException(ExceptionInterface $e)
291291
{
292-
$message = sprintf("Exception: Class: \"%s\", Message: \"%s\", Response:\n%s",
293-
\get_class($e),
294-
$e->getMessage(),
295-
$e->getResponse()->getInfo('debug')
296-
);
292+
if (!$this->logger) {
293+
return;
294+
}
295+
296+
$parts = [
297+
sprintf('Exception: Class: "%s"', \get_class($e)),
298+
sprintf('Message: "%s"', $e->getMessage()),
299+
];
300+
301+
if ($e instanceof HttpExceptionInterface) {
302+
$debug = $e->getResponse()->getInfo('debug');
303+
if ($debug) {
304+
$parts[] = "Response:\n".$debug;
305+
}
306+
}
297307

298-
$this->logger && $this->logger->error($message, ['exception' => $e]);
308+
$this->logger->error(implode(', ', $parts), ['exception' => $e]);
299309
}
300310
}

Sdk/Model/Analysis.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717

1818
class Analysis
1919
{
20-
const STATUS_ORDERED = 'ordered';
21-
const STATUS_RUNNING = 'running';
22-
const STATUS_MEASURED = 'measured';
23-
const STATUS_ANALYZED = 'analyzed';
24-
const STATUS_FINISHED = 'finished';
20+
public const STATUS_ORDERED = 'ordered';
21+
22+
public const STATUS_RUNNING = 'running';
23+
24+
public const STATUS_MEASURED = 'measured';
25+
26+
public const STATUS_ANALYZED = 'analyzed';
27+
28+
public const STATUS_FINISHED = 'finished';
2529

2630
/**
2731
* @Type("array<SensioLabs\Insight\Sdk\Model\Link>")

Sdk/Model/Project.php

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,25 @@ class Project
2121
/**
2222
* @see https://github.com/sensiolabs/connect/blob/master/src/SensioLabs/Connect/Api/Entity/Project.php
2323
*/
24-
const TYPE_PHP_WEBSITE = 0;
25-
const TYPE_PHP_LIBRARY = 1;
26-
const TYPE_SYMFONY2_BUNDLE = 2;
27-
const TYPE_SYMFONY1_PLUGIN = 4;
28-
const TYPE_OTHER = 6;
29-
const TYPE_DRUPAL_MODULE = 7;
30-
const TYPE_LARAVAL_WEB_PROJECT = 8;
31-
const TYPE_SILEX_WEB_PROJECT = 9;
32-
const TYPE_SYMFONY2_WEB_PROJECT = 10;
33-
const TYPE_SYMFONY1_WEB_PROJECT = 11;
24+
public const TYPE_PHP_WEBSITE = 0;
25+
26+
public const TYPE_PHP_LIBRARY = 1;
27+
28+
public const TYPE_SYMFONY2_BUNDLE = 2;
29+
30+
public const TYPE_SYMFONY1_PLUGIN = 4;
31+
32+
public const TYPE_OTHER = 6;
33+
34+
public const TYPE_DRUPAL_MODULE = 7;
35+
36+
public const TYPE_LARAVAL_WEB_PROJECT = 8;
37+
38+
public const TYPE_SILEX_WEB_PROJECT = 9;
39+
40+
public const TYPE_SYMFONY2_WEB_PROJECT = 10;
41+
42+
public const TYPE_SYMFONY1_WEB_PROJECT = 11;
3443

3544
/**
3645
* @Exclude()

bin/insight

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ if (file_exists($a = __DIR__.'/../../../autoload.php')) {
1818
}
1919

2020
use SensioLabs\Insight\Cli\Application;
21+
use Symfony\Component\EventDispatcher\EventDispatcher;
22+
use SensioLabs\Insight\Cli\EventListener\ApiErrorListener;
2123

2224
$application = new Application();
23-
25+
$dispatcher = new EventDispatcher();
26+
$dispatcher->addSubscriber(new ApiErrorListener());
27+
$application->setDispatcher($dispatcher);
2428
$application->run();

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"psr/log": "^1.0",
1111
"symfony/http-client": "^5.4|^6.4|^7.0",
1212
"symfony/console": "^5.4|^6.4|^7.0",
13-
"symfony/expression-language": "^5.4|^6.4|^7.0"
13+
"symfony/expression-language": "^5.4|^6.4|^7.0",
14+
"symfony/event-dispatcher": "^5.4|^6.4|^7.0"
1415
},
1516
"require-dev": {
1617
"monolog/monolog": "^1.4",

0 commit comments

Comments
 (0)