In Magento 2 when post graphql with empty query it results into 500 error.
It should not give 500 error and proper response.
{
"errors": [
{
"message": "Syntax Error: Unexpected <EOF>",
"locations": [
{
"line": 1,
"column": 1
}
],
"extensions": {
"file": "/var/www/html/vendor/webonyx/graphql-php/src/Language/Parser.php",
"line": 437
}
}
]
}
1 Answer 1
If you want to prevent empty GraphQL requests in Magento 2 and return a proper error response when the request body is empty or invalid JSON, you can create a plugin for the GraphQL controller.
Step 1: Add a plugin in di.xml
<type name="Magento\GraphQl\Controller\GraphQl">
<plugin name="prevent_empty_graphql"
type="Vendor\Module\Plugin\PreventEmptyGraphQl"
sortOrder="10"/>
Step 2: Create the plugin class PreventEmptyGraphQl.php
<?php
namespace Vendor\Module\Plugin;
use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\Result\JsonFactory; use Magento\Framework\App\Response\Http as HttpResponse; use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\SerializerInterface;
class PreventEmptyGraphQl { protected $jsonFactory; protected $response; private $httpResponse; private $jsonSerializer;
public function __construct(
JsonFactory $jsonFactory,
ResponseInterface $response,
HttpResponse $httpResponse = null,
SerializerInterface $jsonSerializer
) {
$this->jsonFactory = $jsonFactory;
$this->response = $response;
$this->httpResponse = $httpResponse ?: ObjectManager::getInstance()->get(HttpResponse::class);
$this->jsonSerializer = $jsonSerializer;
}
public function aroundDispatch(
\Magento\GraphQl\Controller\GraphQl $subject,
callable $proceed,
RequestInterface $request
) {
$content = trim((string)$request->getContent());
if ($request->isPost()) {
try {
$data = $this->jsonSerializer->unserialize($content);
} catch (\InvalidArgumentException $e) {
$result = $this->jsonFactory->create();
$result->setHttpResponseCode(400);
$result->setData(['error' => 'Invalid JSON in request body']);
$result->renderResult($this->httpResponse);
return $this->httpResponse;
}
}
return $proceed($request);
}
}