From 3476e3c8c17dfe96a7777bffc18f2636c0fb00a9 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Sun, 7 Sep 2025 18:11:51 +0700 Subject: [PATCH 01/14] refactor middleware fallback handler --- CHANGELOG.md | 2 +- config/di.php | 15 ++++++ src/BadRequestHandler.php | 20 ++------ src/BadRequestHandlerInterface.php | 11 ++--- src/RequestBodyParser.php | 21 ++------ tests/BadRequestHandlerTest.php | 12 +++-- tests/RequestBodyParsersTest.php | 78 ++++++++++++------------------ 7 files changed, 70 insertions(+), 89 deletions(-) create mode 100644 config/di.php diff --git a/CHANGELOG.md b/CHANGELOG.md index dad3c7f..d5c53c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.1.2 under development -- no changes in this release. +- Enh #XX: Refactor `RequestBodyParser` middleware fallback handling (@olegbaturin) ## 1.1.1 June 03, 2024 diff --git a/config/di.php b/config/di.php new file mode 100644 index 0000000..a857186 --- /dev/null +++ b/config/di.php @@ -0,0 +1,15 @@ + [ + '__construct()' => [ + 'badRequestHandler' => Reference::to(BadRequestHandler::class), + ], + ], +]; diff --git a/src/BadRequestHandler.php b/src/BadRequestHandler.php index f5e258d..ac758b4 100644 --- a/src/BadRequestHandler.php +++ b/src/BadRequestHandler.php @@ -15,34 +15,22 @@ */ final class BadRequestHandler implements BadRequestHandlerInterface { - private ResponseFactoryInterface $responseFactory; - private ?ParserException $parserException = null; - - public function __construct(ResponseFactoryInterface $responseFactory) - { - $this->responseFactory = $responseFactory; + public function __construct(private readonly ResponseFactoryInterface $responseFactory) { } - public function handle(ServerRequestInterface $request): ResponseInterface + public function handle(ServerRequestInterface $request, ?ParserException $e = null): ResponseInterface { $response = $this->responseFactory->createResponse(Status::BAD_REQUEST); $response ->getBody() ->write(Status::TEXTS[Status::BAD_REQUEST]); - if ($this->parserException !== null) { + if ($e !== null) { $response ->getBody() - ->write("\n" . $this->parserException->getMessage()); + ->write("\n" . $e->getMessage()); } return $response; } - - public function withParserException(ParserException $e): BadRequestHandlerInterface - { - $new = clone $this; - $new->parserException = $e; - return $new; - } } diff --git a/src/BadRequestHandlerInterface.php b/src/BadRequestHandlerInterface.php index 9bb472c..f1e0215 100644 --- a/src/BadRequestHandlerInterface.php +++ b/src/BadRequestHandlerInterface.php @@ -4,19 +4,18 @@ namespace Yiisoft\Request\Body; -use Psr\Http\Server\RequestHandlerInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; /** * Forms response when there is an error parsing request. */ -interface BadRequestHandlerInterface extends RequestHandlerInterface +interface BadRequestHandlerInterface { /** - * Creates new instance of handler with parser exception set. + * Handles a `ParserException` object and produces a response. * * @param ParserException $e Exception occurred during parsing request. - * - * @return self */ - public function withParserException(ParserException $e): self; + public function handle(ServerRequestInterface $request, ?ParserException $e = null): ResponseInterface; } diff --git a/src/RequestBodyParser.php b/src/RequestBodyParser.php index 37282c7..12f2be7 100644 --- a/src/RequestBodyParser.php +++ b/src/RequestBodyParser.php @@ -6,7 +6,6 @@ use InvalidArgumentException; use Psr\Container\ContainerInterface; -use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; @@ -29,9 +28,6 @@ */ final class RequestBodyParser implements MiddlewareInterface { - private ContainerInterface $container; - private BadRequestHandlerInterface $badRequestHandler; - /** * @var string[] * @psalm-var array @@ -39,16 +35,11 @@ final class RequestBodyParser implements MiddlewareInterface private array $parsers = [ 'application/json' => JsonParser::class, ]; - private bool $ignoreBadRequestBody = false; public function __construct( - ResponseFactoryInterface $responseFactory, - ContainerInterface $container, - BadRequestHandlerInterface $badRequestHandler = null - ) { - $this->container = $container; - $this->badRequestHandler = $badRequestHandler ?? new BadRequestHandler($responseFactory); - } + private readonly ContainerInterface $container, + private readonly ?BadRequestHandlerInterface $badRequestHandler = null + ) {} /** * Registers a request parser for a mime type specified. @@ -122,10 +113,8 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface } $request = $request->withParsedBody($parsed); } catch (ParserException $e) { - if (!$this->ignoreBadRequestBody) { - return $this->badRequestHandler - ->withParserException($e) - ->handle($request); + if ($this->badRequestHandler !== null) { + return $this->badRequestHandler->handle($request, $e); } } } diff --git a/tests/BadRequestHandlerTest.php b/tests/BadRequestHandlerTest.php index a965bcf..3f6b344 100644 --- a/tests/BadRequestHandlerTest.php +++ b/tests/BadRequestHandlerTest.php @@ -11,23 +11,27 @@ use Yiisoft\Http\Method; use Yiisoft\Http\Status; use Yiisoft\Request\Body\BadRequestHandler; +use Yiisoft\Request\Body\ParserException; final class BadRequestHandlerTest extends TestCase { - public function testShouldReturnCode400(): void + public function testShouldReturnCode400AndCorrectErrorInBody(): void { $response = $this ->createHandler() ->handle($this->createRequest()); $this->assertEquals(Status::BAD_REQUEST, $response->getStatusCode()); + $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST], (string)$response->getBody()); } - public function testShouldReturnCorrectErrorInBody(): void + public function testShouldReturnCode400AndExceptionMessageInBody(): void { + $e = new ParserException('JGURDA'); $response = $this ->createHandler() - ->handle($this->createRequest()); - $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST], (string)$response->getBody()); + ->handle($this->createRequest(), $e); + $this->assertEquals(Status::BAD_REQUEST, $response->getStatusCode()); + $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST]. "\n" . $e->getMessage(), (string)$response->getBody()); } private function createHandler(): BadRequestHandler diff --git a/tests/RequestBodyParsersTest.php b/tests/RequestBodyParsersTest.php index c5283d9..15ad0e8 100644 --- a/tests/RequestBodyParsersTest.php +++ b/tests/RequestBodyParsersTest.php @@ -12,8 +12,10 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamInterface; +use Psr\Http\Server\RequestHandlerInterface; use Yiisoft\Http\Header; use Yiisoft\Http\Status; +use Yiisoft\Request\Body\BadRequestHandler; use Yiisoft\Request\Body\BadRequestHandlerInterface; use Yiisoft\Request\Body\Parser\JsonParser; use Yiisoft\Request\Body\ParserException; @@ -54,7 +56,7 @@ public function testWithParserWithEmptyParserClass(): void public function testWithoutParsers(): void { - $container = $this->getContainerWithResponseFactory(); + $container = $this->getContainer(); $bodyParser = $this ->getRequestBodyParser($container) ->withoutParsers(); @@ -69,7 +71,7 @@ public function testWithoutParsers(): void public function testWithoutParser(): void { - $container = $this->getContainerWithResponseFactory(); + $container = $this->getContainer(); $bodyParser = $this ->getRequestBodyParser($container) ->withoutParsers('application/json'); @@ -82,20 +84,6 @@ public function testWithoutParser(): void $this->assertNull($requestHandler->getRequestParsedBody()); } - public function testWithBadRequestResponse(): void - { - $container = $this->getContainerWithResponseFactory(); - $bodyParser = $this->getRequestBodyParser($container); - - $rawBody = '{"test": invalid json}'; - - $requestHandler = $this->createHandler(); - $response = $bodyParser->process($this->createMockRequest('application/json', $rawBody), $requestHandler); - - $this->assertSame(Status::BAD_REQUEST, $response->getStatusCode()); - $this->assertSame(Status::TEXTS[Status::BAD_REQUEST] . "\nInvalid JSON data in request body: Syntax error", (string)$response->getBody()); - } - public function testWithoutBadRequestResponse(): void { $containerId = 'test'; @@ -103,8 +91,7 @@ public function testWithoutBadRequestResponse(): void $mimeType = 'test/test'; $bodyParser = $this ->getRequestBodyParser($container) - ->withParser($mimeType, $containerId) - ->ignoreBadRequestBody(); + ->withParser($mimeType, $containerId); $requestHandler = $this->createHandler(); $response = $bodyParser->process($this->createMockRequest($mimeType), $requestHandler); @@ -112,9 +99,24 @@ public function testWithoutBadRequestResponse(): void $this->assertSame(Status::OK, $response->getStatusCode()); } + public function testWithDefaultBadRequestResponse(): void + { + $container = $this->getContainer(); + $badResponseHandler = $this->createDefaultBadResponseHandler(); + $bodyParser = $this->getRequestBodyParser($container, $badResponseHandler); + + $rawBody = '{"test": invalid json}'; + + $requestHandler = $this->createHandler(); + $response = $bodyParser->process($this->createMockRequest('application/json', $rawBody), $requestHandler); + + $this->assertSame(Status::BAD_REQUEST, $response->getStatusCode()); + $this->assertSame(Status::TEXTS[Status::BAD_REQUEST] . "\n" . 'Invalid JSON data in request body: Syntax error', (string)$response->getBody()); + } + public function testWithCustomBadRequestResponse(): void { - $container = $this->getContainerWithResponseFactory(); + $container = $this->getContainer(); $customBody = 'custom response'; $badResponseHandler = $this->createCustomBadResponseHandler($customBody); @@ -135,7 +137,7 @@ public function testThrownExceptionWithNotExistsParser(): void $this->expectExceptionMessage('The parser "invalidParser" cannot be found.'); $this - ->getRequestBodyParser($this->getContainerWithResponseFactory()) + ->getRequestBodyParser($this->getContainer()) ->withParser('test/test', 'invalidParser'); } @@ -152,13 +154,10 @@ public function testThrownExceptionWithInvalidMimeType(): void ->withParser('invalid mimeType', $containerId); } - private function getContainerWithResponseFactory(): SimpleContainer + private function getContainer(): SimpleContainer { return new SimpleContainer( [ - ResponseFactoryInterface::class => static function () { - return new Psr17Factory(); - }, JsonParser::class => new JsonParser(), ] ); @@ -168,7 +167,6 @@ private function getContainerWithParser(string $id, $expectedOutput, bool $throw { return new SimpleContainer( [ - ResponseFactoryInterface::class => $this->createMock(ResponseFactoryInterface::class), $id => new MockParser($expectedOutput, $throwException), ] ); @@ -186,14 +184,14 @@ private function createMockRequest(string $contentType, string $rawBody = null): return new ServerRequest('POST', '/', [Header::CONTENT_TYPE => $contentType], $body ?? null); } - private function createHandler(): BadRequestHandlerInterface + private function createHandler(): RequestHandlerInterface { $mockResponse = $this->createMock(ResponseInterface::class); $mockResponse ->method('getStatusCode') ->willReturn(Status::OK); - return new class ($mockResponse) implements BadRequestHandlerInterface { + return new class ($mockResponse) implements RequestHandlerInterface { private $requestParsedBody; private ResponseInterface $mockResponse; @@ -215,25 +213,19 @@ public function getRequestParsedBody() { return $this->requestParsedBody; } - - public function withParserException(ParserException $e): BadRequestHandlerInterface - { - // do nothing - return $this; - } }; } - private function getFactory(): ResponseFactoryInterface - { - return new Psr17Factory(); - } - private function getRequestBodyParser( SimpleContainer $container, BadRequestHandlerInterface $badRequestHandler = null ): RequestBodyParser { - return new RequestBodyParser($this->getFactory(), $container, $badRequestHandler); + return new RequestBodyParser($container, $badRequestHandler); + } + + private function createDefaultBadResponseHandler(): BadRequestHandler + { + return new BadRequestHandler(new Psr17Factory()); } private function createCustomBadResponseHandler(string $body): BadRequestHandlerInterface @@ -248,7 +240,7 @@ public function __construct(string $body, ResponseFactoryInterface $responseFact $this->responseFactory = $responseFactory; } - public function handle(ServerRequestInterface $request): ResponseInterface + public function handle(ServerRequestInterface $request, ?ParserException $e = null): ResponseInterface { $response = $this->responseFactory->createResponse(Status::BAD_REQUEST); $response @@ -256,12 +248,6 @@ public function handle(ServerRequestInterface $request): ResponseInterface ->write($this->body); return $response; } - - public function withParserException(ParserException $e): BadRequestHandlerInterface - { - // do nothing - return $this; - } }; } } From b7699c4c8410e3a041a23d16fd82c18dbb92cd76 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Sun, 7 Sep 2025 18:13:48 +0700 Subject: [PATCH 02/14] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5c53c2..be1c370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.1.2 under development -- Enh #XX: Refactor `RequestBodyParser` middleware fallback handling (@olegbaturin) +- Enh #43: Refactor `RequestBodyParser` middleware fallback handling (@olegbaturin) ## 1.1.1 June 03, 2024 From 64aa63a45f85112b8bb512ea2a5de211e38df6d1 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Sun, 7 Sep 2025 18:28:50 +0700 Subject: [PATCH 03/14] fix style --- src/BadRequestHandler.php | 3 ++- src/RequestBodyParser.php | 15 ++------------- tests/BadRequestHandlerTest.php | 2 +- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/BadRequestHandler.php b/src/BadRequestHandler.php index ac758b4..03420d0 100644 --- a/src/BadRequestHandler.php +++ b/src/BadRequestHandler.php @@ -15,7 +15,8 @@ */ final class BadRequestHandler implements BadRequestHandlerInterface { - public function __construct(private readonly ResponseFactoryInterface $responseFactory) { + public function __construct(private readonly ResponseFactoryInterface $responseFactory) + { } public function handle(ServerRequestInterface $request, ?ParserException $e = null): ResponseInterface diff --git a/src/RequestBodyParser.php b/src/RequestBodyParser.php index 12f2be7..78b8df1 100644 --- a/src/RequestBodyParser.php +++ b/src/RequestBodyParser.php @@ -39,7 +39,8 @@ final class RequestBodyParser implements MiddlewareInterface public function __construct( private readonly ContainerInterface $container, private readonly ?BadRequestHandlerInterface $badRequestHandler = null - ) {} + ) { + } /** * Registers a request parser for a mime type specified. @@ -86,18 +87,6 @@ public function withoutParsers(string ...$mimeTypes): self return $new; } - /** - * Makes the middleware to simple skip requests it cannot parse. - * - * @return self - */ - public function ignoreBadRequestBody(): self - { - $new = clone $this; - $new->ignoreBadRequestBody = true; - return $new; - } - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $parser = $this->getParser($this->getContentType($request)); diff --git a/tests/BadRequestHandlerTest.php b/tests/BadRequestHandlerTest.php index 3f6b344..04826e9 100644 --- a/tests/BadRequestHandlerTest.php +++ b/tests/BadRequestHandlerTest.php @@ -31,7 +31,7 @@ public function testShouldReturnCode400AndExceptionMessageInBody(): void ->createHandler() ->handle($this->createRequest(), $e); $this->assertEquals(Status::BAD_REQUEST, $response->getStatusCode()); - $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST]. "\n" . $e->getMessage(), (string)$response->getBody()); + $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST] . "\n" . $e->getMessage(), (string)$response->getBody()); } private function createHandler(): BadRequestHandler From 4d3d7625668a254b6ca2b376b3c1756375981098 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Mon, 8 Sep 2025 15:35:01 +0700 Subject: [PATCH 04/14] change php to 8.1-8.4 update require-dev fix psalm --- .github/workflows/build.yml | 2 +- .github/workflows/static.yml | 2 +- CHANGELOG.md | 1 + composer.json | 14 ++++----- phpunit.xml.dist | 23 +++++++++----- psalm.xml | 8 ++++- src/BadRequestHandler.php | 1 - src/Parser/JsonParser.php | 3 +- src/ParserException.php | 2 +- src/RequestBodyParser.php | 53 ++++++++++++++++++--------------- tests/BadRequestHandlerTest.php | 2 ++ 11 files changed, 67 insertions(+), 44 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0dde6b6..c352354 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,4 +28,4 @@ jobs: os: >- ['ubuntu-latest', 'windows-latest'] php: >- - ['7.4', '8.0', '8.1'] + ['8.0', '8.1', '8.2', '8.3', '8.4'] diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 40ac260..6f3d81a 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -28,4 +28,4 @@ jobs: os: >- ['ubuntu-latest'] php: >- - ['7.4', '8.0', '8.1'] + ['8.0', '8.1', '8.2', '8.3', '8.4'] diff --git a/CHANGELOG.md b/CHANGELOG.md index be1c370..135e6ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 1.1.2 under development - Enh #43: Refactor `RequestBodyParser` middleware fallback handling (@olegbaturin) +- Chg #43: Change PHP constraint in composer.json to 8.1 - 8.4 (@olegbaturin) ## 1.1.1 June 03, 2024 diff --git a/composer.json b/composer.json index c62e182..817cd1c 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ } ], "require": { - "php": "^7.4|^8.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "ext-json": "*", "psr/container": "^1.0|^2.0", "psr/http-message": "^1.0|^2.0", @@ -39,12 +39,12 @@ "yiisoft/http": "^1.2" }, "require-dev": { - "nyholm/psr7": "^1.0", - "phpunit/phpunit": "^9.5", - "roave/infection-static-analysis-plugin": "^1.16", - "spatie/phpunit-watcher": "^1.23", - "vimeo/psalm": "^4.18", - "yiisoft/test-support": "^1.3" + "nyholm/psr7": "^1.8.2", + "phpunit/phpunit": "^10.5.45", + "roave/infection-static-analysis-plugin": "^1.35", + "spatie/phpunit-watcher": "^1.24", + "vimeo/psalm": "^5.26.1 || ^6.8.6", + "yiisoft/test-support": "^3.0.1" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 2e467ae..e7c607b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,11 +1,19 @@ - + failOnWarning="true" + stopOnFailure="false" + colors="true" + displayDetailsOnPhpunitDeprecations="true" +> @@ -16,9 +24,10 @@ - + - ./src + ./src + ./config - + diff --git a/psalm.xml b/psalm.xml index 3240886..9f55f16 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,7 +1,8 @@ + + + + + diff --git a/src/BadRequestHandler.php b/src/BadRequestHandler.php index 03420d0..721d55c 100644 --- a/src/BadRequestHandler.php +++ b/src/BadRequestHandler.php @@ -7,7 +7,6 @@ use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; - use Yiisoft\Http\Status; /** diff --git a/src/Parser/JsonParser.php b/src/Parser/JsonParser.php index 72b739b..c6f1440 100644 --- a/src/Parser/JsonParser.php +++ b/src/Parser/JsonParser.php @@ -18,12 +18,13 @@ final class JsonParser implements ParserInterface { private bool $convertToAssociativeArray; + /** @var int<1, 2147483647> */ private int $depth; private int $options; /** * @param bool $convertToAssociativeArray Whether objects should be converted to associative array during parsing. - * @param int $depth Maximum JSON recursion depth. + * @param int<1, 2147483647> $depth Maximum JSON recursion depth. * @param int $options JSON decoding options. {@see json_decode()}. */ public function __construct( diff --git a/src/ParserException.php b/src/ParserException.php index 3d06613..c25cf4c 100644 --- a/src/ParserException.php +++ b/src/ParserException.php @@ -7,6 +7,6 @@ /** * Exception during parsing request. */ -class ParserException extends \RuntimeException +final class ParserException extends \RuntimeException { } diff --git a/src/RequestBodyParser.php b/src/RequestBodyParser.php index 78b8df1..359e1c4 100644 --- a/src/RequestBodyParser.php +++ b/src/RequestBodyParser.php @@ -36,12 +36,41 @@ final class RequestBodyParser implements MiddlewareInterface 'application/json' => JsonParser::class, ]; + /** + * @param ContainerInterface $container PSR-11 container to create parsers. + * @param BadRequestHandlerInterface|null $badRequestHandler Handler for request parsing errors. + * If set to `null`, the request will continue processing unaltered. Defaults to `null`. + */ public function __construct( private readonly ContainerInterface $container, private readonly ?BadRequestHandlerInterface $badRequestHandler = null ) { } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $parser = $this->getParser($this->getContentType($request)); + if ($parser !== null) { + try { + /** @var mixed $parsed */ + $parsed = $parser->parse((string)$request->getBody()); + if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) { + $parserClass = get_class($parser); + throw new RuntimeException( + "$parserClass::parse() return value must be an array, an object, or null." + ); + } + $request = $request->withParsedBody($parsed); + } catch (ParserException $e) { + if ($this->badRequestHandler !== null) { + return $this->badRequestHandler->handle($request, $e); + } + } + } + + return $handler->handle($request); + } + /** * Registers a request parser for a mime type specified. * @@ -87,30 +116,6 @@ public function withoutParsers(string ...$mimeTypes): self return $new; } - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface - { - $parser = $this->getParser($this->getContentType($request)); - if ($parser !== null) { - try { - /** @var mixed $parsed */ - $parsed = $parser->parse((string)$request->getBody()); - if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) { - $parserClass = get_class($parser); - throw new RuntimeException( - "$parserClass::parse() return value must be an array, an object, or null." - ); - } - $request = $request->withParsedBody($parsed); - } catch (ParserException $e) { - if ($this->badRequestHandler !== null) { - return $this->badRequestHandler->handle($request, $e); - } - } - } - - return $handler->handle($request); - } - /** * @psalm-suppress MixedInferredReturnType, MixedReturnStatement */ diff --git a/tests/BadRequestHandlerTest.php b/tests/BadRequestHandlerTest.php index 04826e9..e09caa1 100644 --- a/tests/BadRequestHandlerTest.php +++ b/tests/BadRequestHandlerTest.php @@ -20,6 +20,7 @@ public function testShouldReturnCode400AndCorrectErrorInBody(): void $response = $this ->createHandler() ->handle($this->createRequest()); + $this->assertEquals(Status::BAD_REQUEST, $response->getStatusCode()); $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST], (string)$response->getBody()); } @@ -30,6 +31,7 @@ public function testShouldReturnCode400AndExceptionMessageInBody(): void $response = $this ->createHandler() ->handle($this->createRequest(), $e); + $this->assertEquals(Status::BAD_REQUEST, $response->getStatusCode()); $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST] . "\n" . $e->getMessage(), (string)$response->getBody()); } From bb649de775e1bb262cb6dc3c93d27b1542dcb20d Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Mon, 8 Sep 2025 15:52:05 +0700 Subject: [PATCH 05/14] fix php min ver to 8.1 --- .github/workflows/build.yml | 2 +- .github/workflows/static.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c352354..8ad564c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,4 +28,4 @@ jobs: os: >- ['ubuntu-latest', 'windows-latest'] php: >- - ['8.0', '8.1', '8.2', '8.3', '8.4'] + ['8.1', '8.2', '8.3', '8.4'] diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 6f3d81a..837d070 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -28,4 +28,4 @@ jobs: os: >- ['ubuntu-latest'] php: >- - ['8.0', '8.1', '8.2', '8.3', '8.4'] + ['8.1', '8.2', '8.3', '8.4'] From c1abcf9cf41921723f6ea569754ea69b06235237 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Tue, 9 Sep 2025 13:58:46 +0700 Subject: [PATCH 06/14] $badRequestAction is a required parameter rename handler to action --- config/di.php | 4 ++-- ...adRequestHandler.php => BadRequestAction.php} | 2 +- ...terface.php => BadRequestActionInterface.php} | 2 +- src/RequestBodyParser.php | 10 +++++----- ...tHandlerTest.php => BadRequestActionTest.php} | 8 ++++---- tests/RequestBodyParsersTest.php | 16 ++++++++-------- 6 files changed, 21 insertions(+), 21 deletions(-) rename src/{BadRequestHandler.php => BadRequestAction.php} (92%) rename src/{BadRequestHandlerInterface.php => BadRequestActionInterface.php} (93%) rename tests/{BadRequestHandlerTest.php => BadRequestActionTest.php} (85%) diff --git a/config/di.php b/config/di.php index a857186..3bd13a0 100644 --- a/config/di.php +++ b/config/di.php @@ -3,13 +3,13 @@ declare(strict_types=1); use Yiisoft\Definitions\Reference; -use Yiisoft\Request\Body\BadRequestHandler; +use Yiisoft\Request\Body\BadRequestAction; use Yiisoft\Request\Body\RequestBodyParser; return [ RequestBodyParser::class => [ '__construct()' => [ - 'badRequestHandler' => Reference::to(BadRequestHandler::class), + 'badRequestAction' => Reference::to(BadRequestAction::class), ], ], ]; diff --git a/src/BadRequestHandler.php b/src/BadRequestAction.php similarity index 92% rename from src/BadRequestHandler.php rename to src/BadRequestAction.php index 721d55c..40be482 100644 --- a/src/BadRequestHandler.php +++ b/src/BadRequestAction.php @@ -12,7 +12,7 @@ /** * Default handler that is used when there is an error during parsing a request. */ -final class BadRequestHandler implements BadRequestHandlerInterface +final class BadRequestAction implements BadRequestActionInterface { public function __construct(private readonly ResponseFactoryInterface $responseFactory) { diff --git a/src/BadRequestHandlerInterface.php b/src/BadRequestActionInterface.php similarity index 93% rename from src/BadRequestHandlerInterface.php rename to src/BadRequestActionInterface.php index f1e0215..8e29452 100644 --- a/src/BadRequestHandlerInterface.php +++ b/src/BadRequestActionInterface.php @@ -10,7 +10,7 @@ /** * Forms response when there is an error parsing request. */ -interface BadRequestHandlerInterface +interface BadRequestActionInterface { /** * Handles a `ParserException` object and produces a response. diff --git a/src/RequestBodyParser.php b/src/RequestBodyParser.php index 359e1c4..e3b449f 100644 --- a/src/RequestBodyParser.php +++ b/src/RequestBodyParser.php @@ -38,12 +38,12 @@ final class RequestBodyParser implements MiddlewareInterface /** * @param ContainerInterface $container PSR-11 container to create parsers. - * @param BadRequestHandlerInterface|null $badRequestHandler Handler for request parsing errors. - * If set to `null`, the request will continue processing unaltered. Defaults to `null`. + * @param BadRequestActionInterface|null $badRequestAction Handler for request parsing errors. + * If set to `null`, the request will continue processing unaltered. */ public function __construct( private readonly ContainerInterface $container, - private readonly ?BadRequestHandlerInterface $badRequestHandler = null + private readonly BadRequestActionInterface|null $badRequestAction ) { } @@ -62,8 +62,8 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface } $request = $request->withParsedBody($parsed); } catch (ParserException $e) { - if ($this->badRequestHandler !== null) { - return $this->badRequestHandler->handle($request, $e); + if ($this->badRequestAction !== null) { + return $this->badRequestAction->handle($request, $e); } } } diff --git a/tests/BadRequestHandlerTest.php b/tests/BadRequestActionTest.php similarity index 85% rename from tests/BadRequestHandlerTest.php rename to tests/BadRequestActionTest.php index e09caa1..7cbe69a 100644 --- a/tests/BadRequestHandlerTest.php +++ b/tests/BadRequestActionTest.php @@ -10,10 +10,10 @@ use Psr\Http\Message\ServerRequestInterface; use Yiisoft\Http\Method; use Yiisoft\Http\Status; -use Yiisoft\Request\Body\BadRequestHandler; +use Yiisoft\Request\Body\BadRequestAction; use Yiisoft\Request\Body\ParserException; -final class BadRequestHandlerTest extends TestCase +final class BadRequestActionTest extends TestCase { public function testShouldReturnCode400AndCorrectErrorInBody(): void { @@ -36,9 +36,9 @@ public function testShouldReturnCode400AndExceptionMessageInBody(): void $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST] . "\n" . $e->getMessage(), (string)$response->getBody()); } - private function createHandler(): BadRequestHandler + private function createHandler(): BadRequestAction { - return new BadRequestHandler(new Psr17Factory()); + return new BadRequestAction(new Psr17Factory()); } private function createRequest(string $uri = '/'): ServerRequestInterface diff --git a/tests/RequestBodyParsersTest.php b/tests/RequestBodyParsersTest.php index 15ad0e8..575c532 100644 --- a/tests/RequestBodyParsersTest.php +++ b/tests/RequestBodyParsersTest.php @@ -15,8 +15,8 @@ use Psr\Http\Server\RequestHandlerInterface; use Yiisoft\Http\Header; use Yiisoft\Http\Status; -use Yiisoft\Request\Body\BadRequestHandler; -use Yiisoft\Request\Body\BadRequestHandlerInterface; +use Yiisoft\Request\Body\BadRequestAction; +use Yiisoft\Request\Body\BadRequestActionInterface; use Yiisoft\Request\Body\Parser\JsonParser; use Yiisoft\Request\Body\ParserException; use Yiisoft\Request\Body\RequestBodyParser; @@ -218,19 +218,19 @@ public function getRequestParsedBody() private function getRequestBodyParser( SimpleContainer $container, - BadRequestHandlerInterface $badRequestHandler = null + BadRequestActionInterface $badRequestAction = null ): RequestBodyParser { - return new RequestBodyParser($container, $badRequestHandler); + return new RequestBodyParser($container, $badRequestAction); } - private function createDefaultBadResponseHandler(): BadRequestHandler + private function createDefaultBadResponseHandler(): BadRequestAction { - return new BadRequestHandler(new Psr17Factory()); + return new BadRequestAction(new Psr17Factory()); } - private function createCustomBadResponseHandler(string $body): BadRequestHandlerInterface + private function createCustomBadResponseHandler(string $body): BadRequestActionInterface { - return new class ($body, new Psr17Factory()) implements BadRequestHandlerInterface { + return new class ($body, new Psr17Factory()) implements BadRequestActionInterface { private string $body; private ResponseFactoryInterface $responseFactory; From 515f1f6c921c7455f567eaebf843a1e7dac224a7 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Tue, 9 Sep 2025 14:26:09 +0700 Subject: [PATCH 07/14] rename config di to di-web --- config/{di.php => di-web.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename config/{di.php => di-web.php} (100%) diff --git a/config/di.php b/config/di-web.php similarity index 100% rename from config/di.php rename to config/di-web.php From ffab1ef8fa2c03cd1678a44da6837305aa608206 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Tue, 16 Sep 2025 16:15:33 +0700 Subject: [PATCH 08/14] rename BadRequestHandler back --- composer.json | 1 + config/di-web.php | 11 ++--- ...equestAction.php => BadRequestHandler.php} | 2 +- ...ace.php => BadRequestHandlerInterface.php} | 2 +- src/RequestBodyParser.php | 8 ++-- ...tionTest.php => BadRequestHandlerTest.php} | 8 ++-- tests/ConfigTest.php | 41 +++++++++++++++++++ tests/RequestBodyParsersTest.php | 16 ++++---- 8 files changed, 63 insertions(+), 26 deletions(-) rename src/{BadRequestAction.php => BadRequestHandler.php} (92%) rename src/{BadRequestActionInterface.php => BadRequestHandlerInterface.php} (93%) rename tests/{BadRequestActionTest.php => BadRequestHandlerTest.php} (85%) create mode 100644 tests/ConfigTest.php diff --git a/composer.json b/composer.json index 817cd1c..2e934dc 100644 --- a/composer.json +++ b/composer.json @@ -44,6 +44,7 @@ "roave/infection-static-analysis-plugin": "^1.35", "spatie/phpunit-watcher": "^1.24", "vimeo/psalm": "^5.26.1 || ^6.8.6", + "yiisoft/di": "^1.4", "yiisoft/test-support": "^3.0.1" }, "autoload": { diff --git a/config/di-web.php b/config/di-web.php index 3bd13a0..7d49d67 100644 --- a/config/di-web.php +++ b/config/di-web.php @@ -2,14 +2,9 @@ declare(strict_types=1); -use Yiisoft\Definitions\Reference; -use Yiisoft\Request\Body\BadRequestAction; -use Yiisoft\Request\Body\RequestBodyParser; +use Yiisoft\Request\Body\BadRequestHandler; +use Yiisoft\Request\Body\BadRequestHandlerInterface; return [ - RequestBodyParser::class => [ - '__construct()' => [ - 'badRequestAction' => Reference::to(BadRequestAction::class), - ], - ], + BadRequestHandlerInterface::class => BadRequestHandler::class, ]; diff --git a/src/BadRequestAction.php b/src/BadRequestHandler.php similarity index 92% rename from src/BadRequestAction.php rename to src/BadRequestHandler.php index 40be482..721d55c 100644 --- a/src/BadRequestAction.php +++ b/src/BadRequestHandler.php @@ -12,7 +12,7 @@ /** * Default handler that is used when there is an error during parsing a request. */ -final class BadRequestAction implements BadRequestActionInterface +final class BadRequestHandler implements BadRequestHandlerInterface { public function __construct(private readonly ResponseFactoryInterface $responseFactory) { diff --git a/src/BadRequestActionInterface.php b/src/BadRequestHandlerInterface.php similarity index 93% rename from src/BadRequestActionInterface.php rename to src/BadRequestHandlerInterface.php index 8e29452..f1e0215 100644 --- a/src/BadRequestActionInterface.php +++ b/src/BadRequestHandlerInterface.php @@ -10,7 +10,7 @@ /** * Forms response when there is an error parsing request. */ -interface BadRequestActionInterface +interface BadRequestHandlerInterface { /** * Handles a `ParserException` object and produces a response. diff --git a/src/RequestBodyParser.php b/src/RequestBodyParser.php index e3b449f..8a73623 100644 --- a/src/RequestBodyParser.php +++ b/src/RequestBodyParser.php @@ -38,12 +38,12 @@ final class RequestBodyParser implements MiddlewareInterface /** * @param ContainerInterface $container PSR-11 container to create parsers. - * @param BadRequestActionInterface|null $badRequestAction Handler for request parsing errors. + * @param BadRequestHandlerInterface|null $badRequestHandler Handler for request parsing errors. * If set to `null`, the request will continue processing unaltered. */ public function __construct( private readonly ContainerInterface $container, - private readonly BadRequestActionInterface|null $badRequestAction + private readonly BadRequestHandlerInterface|null $badRequestHandler ) { } @@ -62,8 +62,8 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface } $request = $request->withParsedBody($parsed); } catch (ParserException $e) { - if ($this->badRequestAction !== null) { - return $this->badRequestAction->handle($request, $e); + if ($this->badRequestHandler !== null) { + return $this->badRequestHandler->handle($request, $e); } } } diff --git a/tests/BadRequestActionTest.php b/tests/BadRequestHandlerTest.php similarity index 85% rename from tests/BadRequestActionTest.php rename to tests/BadRequestHandlerTest.php index 7cbe69a..e09caa1 100644 --- a/tests/BadRequestActionTest.php +++ b/tests/BadRequestHandlerTest.php @@ -10,10 +10,10 @@ use Psr\Http\Message\ServerRequestInterface; use Yiisoft\Http\Method; use Yiisoft\Http\Status; -use Yiisoft\Request\Body\BadRequestAction; +use Yiisoft\Request\Body\BadRequestHandler; use Yiisoft\Request\Body\ParserException; -final class BadRequestActionTest extends TestCase +final class BadRequestHandlerTest extends TestCase { public function testShouldReturnCode400AndCorrectErrorInBody(): void { @@ -36,9 +36,9 @@ public function testShouldReturnCode400AndExceptionMessageInBody(): void $this->assertEquals(Status::TEXTS[Status::BAD_REQUEST] . "\n" . $e->getMessage(), (string)$response->getBody()); } - private function createHandler(): BadRequestAction + private function createHandler(): BadRequestHandler { - return new BadRequestAction(new Psr17Factory()); + return new BadRequestHandler(new Psr17Factory()); } private function createRequest(string $uri = '/'): ServerRequestInterface diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php new file mode 100644 index 0000000..fe4b6ad --- /dev/null +++ b/tests/ConfigTest.php @@ -0,0 +1,41 @@ +createContainer(); + + $requestHandler = $container->get(BadRequestHandlerInterface::class); + $this->assertInstanceOf(BadRequestHandler::class, $requestHandler); + } + + private function createContainer(): Container + { + return new Container( + ContainerConfig::create()->withDefinitions([ + ResponseFactoryInterface::class => Psr17Factory::class, + ...$this->getContainerDefinitions(), + ]) + ); + } + + private function getContainerDefinitions(): array + { + return require dirname(__DIR__) . '/config/di-web.php'; + } +} diff --git a/tests/RequestBodyParsersTest.php b/tests/RequestBodyParsersTest.php index 575c532..15ad0e8 100644 --- a/tests/RequestBodyParsersTest.php +++ b/tests/RequestBodyParsersTest.php @@ -15,8 +15,8 @@ use Psr\Http\Server\RequestHandlerInterface; use Yiisoft\Http\Header; use Yiisoft\Http\Status; -use Yiisoft\Request\Body\BadRequestAction; -use Yiisoft\Request\Body\BadRequestActionInterface; +use Yiisoft\Request\Body\BadRequestHandler; +use Yiisoft\Request\Body\BadRequestHandlerInterface; use Yiisoft\Request\Body\Parser\JsonParser; use Yiisoft\Request\Body\ParserException; use Yiisoft\Request\Body\RequestBodyParser; @@ -218,19 +218,19 @@ public function getRequestParsedBody() private function getRequestBodyParser( SimpleContainer $container, - BadRequestActionInterface $badRequestAction = null + BadRequestHandlerInterface $badRequestHandler = null ): RequestBodyParser { - return new RequestBodyParser($container, $badRequestAction); + return new RequestBodyParser($container, $badRequestHandler); } - private function createDefaultBadResponseHandler(): BadRequestAction + private function createDefaultBadResponseHandler(): BadRequestHandler { - return new BadRequestAction(new Psr17Factory()); + return new BadRequestHandler(new Psr17Factory()); } - private function createCustomBadResponseHandler(string $body): BadRequestActionInterface + private function createCustomBadResponseHandler(string $body): BadRequestHandlerInterface { - return new class ($body, new Psr17Factory()) implements BadRequestActionInterface { + return new class ($body, new Psr17Factory()) implements BadRequestHandlerInterface { private string $body; private ResponseFactoryInterface $responseFactory; From 37e751a9b80a2cb7e9a7d1434e7b1403ec568935 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Wed, 17 Sep 2025 16:14:12 +0700 Subject: [PATCH 09/14] update composer.json config-plugin options --- composer.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/composer.json b/composer.json index 2e934dc..7af9d84 100644 --- a/composer.json +++ b/composer.json @@ -57,6 +57,14 @@ "Yiisoft\\Request\\Body\\Tests\\": "tests" } }, + "extra": { + "config-plugin-options": { + "source-directory": "config" + }, + "config-plugin": { + "di-web": "di-web.php" + } + }, "config": { "sort-packages": true, "allow-plugins": { From 49ea7ecb40eaf899b17a4edb9bb7d4de4ace9afd Mon Sep 17 00:00:00 2001 From: olegbaturin <15981018+olegbaturin@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:05:50 +0000 Subject: [PATCH 10/14] Apply Rector changes (CI) --- tests/RequestBodyParsersTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/RequestBodyParsersTest.php b/tests/RequestBodyParsersTest.php index 8f45a0c..d5acb7a 100644 --- a/tests/RequestBodyParsersTest.php +++ b/tests/RequestBodyParsersTest.php @@ -227,7 +227,7 @@ private function createHandler(): RequestHandlerInterface ->willReturn(Status::OK); return new class ($mockResponse) implements RequestHandlerInterface { - private array|object|null $requestParsedBody; + private array|object|null $requestParsedBody = null; public function __construct( private readonly ResponseInterface $mockResponse, From 335bc50e717635558df224dbed9b000680f87011 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Thu, 25 Sep 2025 20:36:53 +0700 Subject: [PATCH 11/14] update readme --- README.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d00d1fd..fdbbc0f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ server request body selecting the parser according to the server request mime ty ## Requirements -- PHP 7.4 or higher. +- PHP 8.1 or higher. ## Installation @@ -43,6 +43,37 @@ the middleware: $requestBodyParser = $requestBodyParser->withParser('application/myformat', MyFormatParser::class); ``` +## Errors handling + +To handle parsing errors, pass an instance of `BadRequestHandlerInterface` to the `RequestBodyParser` middleware's constructor. +[Yii Request Body Parser](yiisoft/request-body-parser) package provides the `BadRequestHandler` error handler by default. +To use it, add it to the `RequestBodyParser` constructor. + +```php +use Yiisoft\Request\Body\RequestBodyParser; +use Yiisoft\Request\Body\BadRequestHandler; + +$responseFactory = $container->get(\Psr\Http\Message\ResponseFactoryInterface::class); +$BadRequestHandler = new BadRequestHandler($responseFactory); + +$middleware = new RequestBodyParser($container, $BadRequestHandler); +``` + +or define the `BadRequestHandlerInterface` configuration in the [DI container](https://github.com/yiisoft/di): + +```php +// config/web/di/request-body-parser.php +use Yiisoft\Request\Body\BadRequestHandler; +use Yiisoft\Request\Body\BadRequestHandlerInterface; + +return [ + BadRequestHandlerInterface::class => BadRequestHandler::class, +]; +``` + +In case [Yii Request Body Parser](yiisoft/request-body-parser) package is used along with [Yii Config](https://github.com/yiisoft/config) plugin, the package is [configured](./config/di-web.php) +automatically to use `Yiisoft\Request\Body\BadRequestHandler`. + ## Documentation - [Internals](docs/internals.md) From ea7a73de610f4da8a1a4f82593fef2693035cf06 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Sat, 27 Sep 2025 14:29:17 +0700 Subject: [PATCH 12/14] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fdbbc0f..f250d16 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ return [ ``` In case [Yii Request Body Parser](yiisoft/request-body-parser) package is used along with [Yii Config](https://github.com/yiisoft/config) plugin, the package is [configured](./config/di-web.php) -automatically to use `Yiisoft\Request\Body\BadRequestHandler`. +automatically to use `BadRequestHandler`. ## Documentation From c8650b9ecb604e145872bdfb9e3e1d1e1d6b4c56 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Sat, 27 Sep 2025 17:06:34 +0700 Subject: [PATCH 13/14] update readme --- README.md | 25 ++++++++++++++++++++----- src/RequestBodyParser.php | 2 +- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f250d16..6675e29 100644 --- a/README.md +++ b/README.md @@ -46,23 +46,29 @@ $requestBodyParser = $requestBodyParser->withParser('application/myformat', MyFo ## Errors handling To handle parsing errors, pass an instance of `BadRequestHandlerInterface` to the `RequestBodyParser` middleware's constructor. -[Yii Request Body Parser](yiisoft/request-body-parser) package provides the `BadRequestHandler` error handler by default. -To use it, add it to the `RequestBodyParser` constructor. +The [Yii Request Body Parser](yiisoft/request-body-parser) package provides the `BadRequestHandler` error handler by default. + +To use it, pass it to the `RequestBodyParser` middleware constructor. ```php +use Psr\Http\Message\ResponseFactoryInterface; use Yiisoft\Request\Body\RequestBodyParser; use Yiisoft\Request\Body\BadRequestHandler; -$responseFactory = $container->get(\Psr\Http\Message\ResponseFactoryInterface::class); +$responseFactory = $container->get(ResponseFactoryInterface::class); $BadRequestHandler = new BadRequestHandler($responseFactory); -$middleware = new RequestBodyParser($container, $BadRequestHandler); +$middleware = new RequestBodyParser( + $container, + $badRequestHandler // pass the handler here +); ``` or define the `BadRequestHandlerInterface` configuration in the [DI container](https://github.com/yiisoft/di): ```php // config/web/di/request-body-parser.php + use Yiisoft\Request\Body\BadRequestHandler; use Yiisoft\Request\Body\BadRequestHandlerInterface; @@ -71,9 +77,18 @@ return [ ]; ``` -In case [Yii Request Body Parser](yiisoft/request-body-parser) package is used along with [Yii Config](https://github.com/yiisoft/config) plugin, the package is [configured](./config/di-web.php) +> In case [Yii Request Body Parser](yiisoft/request-body-parser) package is used along with [Yii Config](https://github.com/yiisoft/config) plugin, the package is [configured](./config/di-web.php) automatically to use `BadRequestHandler`. +To disable parsing errors handling pass `null` as the `badRequestHandler` parameter of the `RequestBodyParser` middleware constructor: + +```php +$middleware = new Router( + $container, + null // disables parsing errors handling +); +``` + ## Documentation - [Internals](docs/internals.md) diff --git a/src/RequestBodyParser.php b/src/RequestBodyParser.php index eb071a2..1b80122 100644 --- a/src/RequestBodyParser.php +++ b/src/RequestBodyParser.php @@ -47,7 +47,7 @@ final class RequestBodyParser implements MiddlewareInterface */ public function __construct( private readonly ContainerInterface $container, - private readonly BadRequestHandlerInterface|null $badRequestHandler + private readonly ?BadRequestHandlerInterface $badRequestHandler ) { } From 2eefe45339b4014d610a883460153c65a65351d0 Mon Sep 17 00:00:00 2001 From: Oleg Baturin Date: Tue, 30 Sep 2025 13:37:26 +0700 Subject: [PATCH 14/14] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6675e29..31a38ba 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ automatically to use `BadRequestHandler`. To disable parsing errors handling pass `null` as the `badRequestHandler` parameter of the `RequestBodyParser` middleware constructor: ```php -$middleware = new Router( +$middleware = new RequestBodyParser( $container, null // disables parsing errors handling );