Skip to content

Commit 43b522c

Browse files
authored
Consistently throw BadRequestGraphQLException on invalid requests (#10)
1 parent 7d6b247 commit 43b522c

6 files changed

+44
-25
lines changed

.php-cs-fixer.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php declare(strict_types=1);
22

3-
use function MLL\PhpCsFixerConfig\config;
3+
use function MLL\PhpCsFixerConfig\risky;
44

55
$finder = PhpCsFixer\Finder::create()
66
->notPath('vendor')
@@ -9,4 +9,4 @@
99
->ignoreDotFiles(true)
1010
->ignoreVCS(true);
1111

12-
return config($finder);
12+
return risky($finder);

CHANGELOG.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
67

78
## Unreleased
89

10+
## v1.4.0
11+
12+
### Changed
13+
14+
- Consistently throw `BadRequestGraphQLException` on invalid requests
15+
916
## v1.3.0
1017

1118
### Added

composer.json

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
]
5151
},
5252
"config": {
53+
"allow-plugins": {
54+
"infection/extension-installer": true,
55+
"ergebnis/composer-normalize": true,
56+
"phpstan/extension-installer": true
57+
},
5358
"preferred-install": "dist",
5459
"sort-packages": true
5560
}

src/BadRequestGraphQLException.php

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Laragraph\Utils;
4+
5+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
6+
7+
class BadRequestGraphQLException extends BadRequestHttpException
8+
{
9+
}

src/RequestParser.php

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
<?php
2-
3-
declare(strict_types=1);
1+
<?php declare(strict_types=1);
42

53
namespace Laragraph\Utils;
64

75
use GraphQL\Server\Helper;
8-
use GraphQL\Server\OperationParams;
9-
use GraphQL\Server\RequestError;
106
use GraphQL\Utils\Utils;
117
use Illuminate\Http\Request;
128
use Illuminate\Support\Arr;
139
use Illuminate\Support\Str;
10+
use Safe\Exceptions\JsonException;
1411

1512
/**
1613
* Follows https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md.
@@ -30,7 +27,7 @@ public function __construct()
3027
/**
3128
* Converts an incoming HTTP request to one or more OperationParams.
3229
*
33-
* @throws \GraphQL\Server\RequestError
30+
* @throws \Laragraph\Utils\BadRequestGraphQLException
3431
*
3532
* @return \GraphQL\Server\OperationParams|array<int, \GraphQL\Server\OperationParams>
3633
*/
@@ -52,10 +49,14 @@ public function parseRequest(Request $request)
5249
if (Str::startsWith($contentType, ['application/json', 'application/graphql+json'])) {
5350
/** @var string $content */
5451
$content = $request->getContent();
55-
$bodyParams = \Safe\json_decode($content, true);
52+
try {
53+
$bodyParams = \Safe\json_decode($content, true);
54+
} catch (JsonException $e) {
55+
throw new BadRequestGraphQLException("Invalid JSON: {$e->getMessage()}");
56+
}
5657

5758
if (! is_array($bodyParams)) {
58-
throw new RequestError(
59+
throw new BadRequestGraphQLException(
5960
'GraphQL Server expects JSON object or array, but got '
6061
. Utils::printSafeJson($bodyParams)
6162
);
@@ -70,7 +71,7 @@ public function parseRequest(Request $request)
7071
} elseif (Str::startsWith($contentType, 'multipart/form-data')) {
7172
$bodyParams = $this->inlineFiles($request);
7273
} else {
73-
throw new RequestError('Unexpected content type: ' . Utils::printSafeJson($contentType));
74+
throw new BadRequestGraphQLException('Unexpected content type: ' . Utils::printSafeJson($contentType));
7475
}
7576
}
7677

@@ -87,15 +88,15 @@ protected function inlineFiles(Request $request): array
8788
/** @var string|null $mapParam */
8889
$mapParam = $request->post('map');
8990
if (null === $mapParam) {
90-
throw new RequestError(
91+
throw new BadRequestGraphQLException(
9192
'Could not find a valid map, be sure to conform to GraphQL multipart request specification: https://github.com/jaydenseric/graphql-multipart-request-spec'
9293
);
9394
}
9495

9596
/** @var string|null $operationsParam */
9697
$operationsParam = $request->post('operations');
9798
if (null === $operationsParam) {
98-
throw new RequestError(
99+
throw new BadRequestGraphQLException(
99100
'Could not find valid operations, be sure to conform to GraphQL multipart request specification: https://github.com/jaydenseric/graphql-multipart-request-spec'
100101
);
101102
}

tests/Unit/RequestParserTest.php

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
<?php
2-
3-
declare(strict_types=1);
1+
<?php declare(strict_types=1);
42

53
namespace Laragraph\Utils\Tests\Unit;
64

75
use GraphQL\Server\OperationParams;
8-
use GraphQL\Server\RequestError;
96
use Illuminate\Http\Request;
107
use Illuminate\Http\UploadedFile;
8+
use Laragraph\Utils\BadRequestGraphQLException;
119
use Laragraph\Utils\RequestParser;
1210
use Orchestra\Testbench\TestCase;
13-
use Safe\Exceptions\JsonException;
1411
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
1512

16-
class RequestParserTest extends TestCase
13+
final class RequestParserTest extends TestCase
1714
{
1815
public function testGetWithQuery(): void
1916
{
@@ -138,7 +135,7 @@ public function testNonsensicalContentTypes(string $contentType): void
138135
);
139136
$parser = new RequestParser();
140137

141-
$this->expectException(RequestError::class);
138+
$this->expectException(BadRequestGraphQLException::class);
142139
$parser->parseRequest($request);
143140
}
144141

@@ -175,7 +172,7 @@ public function testInvalidJson(): void
175172
);
176173
$parser = new RequestParser();
177174

178-
$this->expectException(JsonException::class);
175+
$this->expectException(BadRequestGraphQLException::class);
179176
$parser->parseRequest($request);
180177
}
181178

@@ -190,7 +187,7 @@ public function testNonArrayJson(): void
190187
);
191188
$parser = new RequestParser();
192189

193-
$this->expectException(RequestError::class);
190+
$this->expectException(BadRequestGraphQLException::class);
194191
$parser->parseRequest($request);
195192
}
196193

@@ -258,7 +255,7 @@ public function testMultipartFormWithoutMap(): void
258255
);
259256
$parser = new RequestParser();
260257

261-
$this->expectException(RequestError::class);
258+
$this->expectException(BadRequestGraphQLException::class);
262259
$parser->parseRequest($request);
263260
}
264261

@@ -281,7 +278,7 @@ public function testMultipartFormWithoutOperations(): void
281278

282279
$parser = new RequestParser();
283280

284-
$this->expectException(RequestError::class);
281+
$this->expectException(BadRequestGraphQLException::class);
285282
$parser->parseRequest($request);
286283
}
287284

0 commit comments

Comments
 (0)