diff --git a/vendor/magento/module-graph-ql/Controller/GraphQl.php b/vendor/magento/module-graph-ql/Controller/GraphQl.php index 103aa00a4651a..8eb62b44710cc 100644 --- a/vendor/magento/module-graph-ql/Controller/GraphQl.php +++ b/vendor/magento/module-graph-ql/Controller/GraphQl.php @@ -10,6 +10,7 @@ use Exception; use GraphQL\Error\FormattedError; use GraphQL\Error\SyntaxError; +use GraphQL\Language\Source; use Magento\Framework\App\Area; use Magento\Framework\App\AreaList; use Magento\Framework\App\FrontControllerInterface; @@ -23,6 +24,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlAuthenticationException; use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\InvalidRequestInterface; use Magento\Framework\GraphQl\Query\Fields as QueryFields; use Magento\Framework\GraphQl\Query\QueryParser; use Magento\Framework\GraphQl\Query\QueryProcessor; @@ -34,7 +36,6 @@ use Magento\GraphQl\Model\GraphQl\RequestConfiguration; use Magento\GraphQl\Model\Query\ContextFactoryInterface; use Magento\GraphQl\Model\Query\Logger\LoggerPool; -use Throwable; /** * Front controller for web API GraphQL area. @@ -252,25 +253,21 @@ public function dispatch(RequestInterface $request): ResponseInterface /** * Handle GraphQL Exceptions * - * @param Exception $error + * @param Exception $e * @return array - * @throws Throwable */ - private function handleGraphQlException(Exception $error): array + private function handleGraphQlException(Exception $e): array { - if ($error instanceof SyntaxError || $error instanceof GraphQlInputException) { - return [['errors' => [FormattedError::createFromException($error)]], 400]; - } - if ($error instanceof GraphQlAuthenticationException) { - return [['errors' => [$this->graphQlError->create($error)]], 401]; - } - if ($error instanceof GraphQlAuthorizationException) { - return [['errors' => [$this->graphQlError->create($error)]], 403]; - } - return [ - ['errors' => [$this->graphQlError->create($error)]], - ExceptionFormatter::HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS - ]; + [$error, $statusCode] = match (true) { + $e instanceof InvalidRequestInterface => [FormattedError::createFromException($e), $e->getStatusCode()], + $e instanceof SyntaxError => [FormattedError::createFromException($e), 400], + $e instanceof GraphQlAuthenticationException => [$this->graphQlError->create($e), 401], + $e instanceof GraphQlAuthorizationException => [$this->graphQlError->create($e), 403], + $e instanceof GraphQlInputException => [FormattedError::createFromException($e), 200], + default => [$this->graphQlError->create($e), ExceptionFormatter::HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS], + }; + + return [['errors' => [$error]], $statusCode]; } /** @@ -299,27 +296,33 @@ private function getHttpResponseCode(array $result): int * * @param RequestInterface $request * @return array - * @throws GraphQlInputException + * @throws SyntaxError */ private function getDataFromRequest(RequestInterface $request): array { $data = []; - try { - /** @var Http $request */ - if ($request->isPost() && $request->getContent()) { - $content = $request->getContent(); - if ($this->maxRequestBodySize > 0 && strlen($content) > $this->maxRequestBodySize) { - throw new GraphQlInputException(__('Request body is too large.')); - } - $data = $this->jsonSerializer->unserialize($request->getContent()); - } elseif ($request->isGet()) { - $data = $request->getParams(); + /** @var Http $request */ + if ($request->isPost() && $request->getContent()) { + $content = $request->getContent(); + if ($this->maxRequestBodySize > 0 && strlen($content) > $this->maxRequestBodySize) { + throw new GraphQlInputException(__('Request body is too large.')); + } + try { + $data = $this->jsonSerializer->unserialize($content); + } catch (\InvalidArgumentException) { + $source = new Source($content); + throw new SyntaxError($source, 0, 'Unable to parse the request.'); + } + } elseif ($request->isGet()) { + $data = $request->getParams(); + try { $data['variables'] = !empty($data['variables']) && is_string($data['variables']) ? $this->jsonSerializer->unserialize($data['variables']) : null; + } catch (\InvalidArgumentException) { + $source = new Source($data['variables']); + throw new SyntaxError($source, 0, 'Unable to parse the variables.'); } - } catch (\InvalidArgumentException $e) { - throw new GraphQlInputException(__('Unable to parse the request.'), $e); } return $data; diff --git a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php index 555048aac6771..a8e6a8478f4ce 100644 --- a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php +++ b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/ContentTypeValidator.php @@ -1,14 +1,15 @@ isPost() && strpos($headerValue, $requiredHeaderValue) === false ) { - throw new GraphQlInputException( - new \Magento\Framework\Phrase('Request content type must be application/json') + throw new UnsupportedMediaTypeException( + new Phrase('Request content type must be application/json') ); } } diff --git a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php index ba50f34c7b709..d41fcaf39aa7b 100644 --- a/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php +++ b/vendor/magento/module-graph-ql/Controller/HttpRequestValidator/HttpVerbValidator.php @@ -1,7 +1,7 @@ isSafe; + } +} diff --git a/vendor/magento/framework/GraphQl/Exception/UnsupportedMediaTypeException.php b/vendor/magento/framework/GraphQl/Exception/UnsupportedMediaTypeException.php new file mode 100644 index 0000000000000..6be650a3eb01b --- /dev/null +++ b/vendor/magento/framework/GraphQl/Exception/UnsupportedMediaTypeException.php @@ -0,0 +1,46 @@ +isSafe; + } +} diff --git a/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php b/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php index 250b80defa6dd..2a81b5d32ced2 100644 --- a/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php +++ b/vendor/magento/framework/GraphQl/Schema/SchemaGenerator.php @@ -1,13 +1,14 @@ $this->typeRegistry->get('Query'), 'mutation' => $this->typeRegistry->get('Mutation'), 'typeLoader' => function ($name) { - return $this->typeRegistry->get($name); + try { + return $this->typeRegistry->get($name); + } catch (GraphQlInputException) { + return null; + } }, 'types' => function () { $typesImplementors = []; diff --git a/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php b/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php index 414e1eebe6531..1b8cb47e4048d 100644 --- a/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php +++ b/vendor/magento/framework/GraphQl/Schema/Type/TypeRegistry.php @@ -1,12 +1,13 @@ types[$typeName])) { - $configElement = $this->config->getConfigElement($typeName); + try { + $configElement = $this->config->getConfigElement($typeName); + } catch (LogicException) { + throw new GraphQlInputException( + new Phrase('Unknown type "%1".', [$typeName]) + ); + } $configElementClass = get_class($configElement); if (!isset($this->configToTypeMap[$configElementClass])) {