diff --git a/VERSION b/VERSION index ccbccc3d..c043eea7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.0 +2.2.1 diff --git a/src/Controller/InfoProviderController.php b/src/Controller/InfoProviderController.php index dae8213e..b79c307c 100644 --- a/src/Controller/InfoProviderController.php +++ b/src/Controller/InfoProviderController.php @@ -25,6 +25,7 @@ namespace App\Controller; use App\Entity\Parts\Manufacturer; use App\Entity\Parts\Part; +use App\Exceptions\OAuthReconnectRequiredException; use App\Form\InfoProviderSystem\PartSearchType; use App\Services\InfoProviderSystem\ExistingPartFinder; use App\Services\InfoProviderSystem\PartInfoRetriever; @@ -175,8 +176,11 @@ class InfoProviderController extends AbstractController $this->addFlash('error',$e->getMessage()); //Log the exception $exceptionLogger->error('Error during info provider search: ' . $e->getMessage(), ['exception' => $e]); + } catch (OAuthReconnectRequiredException $e) { + $this->addFlash('error', t('info_providers.search.error.oauth_reconnect', ['%provider%' => $e->getProviderName()])); } + // modify the array to an array of arrays that has a field for a matching local Part // the advantage to use that format even when we don't look for local parts is that we // always work with the same interface diff --git a/src/Exceptions/OAuthReconnectRequiredException.php b/src/Exceptions/OAuthReconnectRequiredException.php new file mode 100644 index 00000000..97abb19f --- /dev/null +++ b/src/Exceptions/OAuthReconnectRequiredException.php @@ -0,0 +1,48 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Exceptions; + +use Throwable; + +class OAuthReconnectRequiredException extends \RuntimeException +{ + private string $providerName = "unknown"; + + public function __construct(string $message = "You need to reconnect the OAuth connection for this provider!", int $code = 0, ?Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + } + + public static function forProvider(string $providerName): self + { + $exception = new self("You need to reconnect the OAuth connection for the provider '$providerName'!"); + $exception->providerName = $providerName; + return $exception; + } + + public function getProviderName(): string + { + return $this->providerName; + } +} diff --git a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php index 51f460e4..423b5244 100644 --- a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php +++ b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace App\Services\InfoProviderSystem\Providers; use App\Entity\Parts\ManufacturingStatus; +use App\Exceptions\OAuthReconnectRequiredException; use App\Services\InfoProviderSystem\DTOs\FileDTO; use App\Services\InfoProviderSystem\DTOs\ParameterDTO; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; @@ -117,12 +118,22 @@ class DigikeyProvider implements InfoProviderInterface ]; //$response = $this->digikeyClient->request('POST', '/Search/v3/Products/Keyword', [ - $response = $this->digikeyClient->request('POST', '/products/v4/search/keyword', [ - 'json' => $request, - 'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME) - ]); + try { + $response = $this->digikeyClient->request('POST', '/products/v4/search/keyword', [ + 'json' => $request, + 'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME) + ]); + + $response_array = $response->toArray(); + } catch (\InvalidArgumentException $exception) { + //Check if the exception was caused by an invalid or expired token + if (str_contains($exception->getMessage(), 'access_token')) { + throw OAuthReconnectRequiredException::forProvider($this->getProviderKey()); + } + + throw $exception; + } - $response_array = $response->toArray(); $result = []; @@ -150,9 +161,18 @@ class DigikeyProvider implements InfoProviderInterface public function getDetails(string $id): PartDetailDTO { - $response = $this->digikeyClient->request('GET', '/products/v4/search/' . urlencode($id) . '/productdetails', [ - 'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME) - ]); + try { + $response = $this->digikeyClient->request('GET', '/products/v4/search/' . urlencode($id) . '/productdetails', [ + 'auth_bearer' => $this->authTokenManager->getAlwaysValidTokenString(self::OAUTH_APP_NAME) + ]); + } catch (\InvalidArgumentException $exception) { + //Check if the exception was caused by an invalid or expired token + if (str_contains($exception->getMessage(), 'access_token')) { + throw OAuthReconnectRequiredException::forProvider($this->getProviderKey()); + } + + throw $exception; + } $response_array = $response->toArray(); $product = $response_array['Product']; diff --git a/templates/helper.twig b/templates/helper.twig index bd1d2aa7..66268a96 100644 --- a/templates/helper.twig +++ b/templates/helper.twig @@ -214,11 +214,11 @@ {% endmacro %} {% macro parameters_table(parameters) %} - +
- + @@ -240,4 +240,4 @@ {% else %} {{ datetime|format_datetime }} {% endif %} -{% endmacro %} \ No newline at end of file +{% endmacro %} diff --git a/templates/label_system/dialog.html.twig b/templates/label_system/dialog.html.twig index 037b549e..b9149aa3 100644 --- a/templates/label_system/dialog.html.twig +++ b/templates/label_system/dialog.html.twig @@ -10,6 +10,9 @@ {% block card_content %} {{ form_start(form) }} + {# Default submit to use when pressing enter. #} + +
{% trans %}specifications.property{% endtrans %}{% trans %}specifications.symbol{% endtrans %}{% trans %}specifications.symbol{% endtrans %} {% trans %}specifications.value{% endtrans %}