diff --git a/CHANGELOG.md b/CHANGELOG.md index 75b0601..070d2fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased] + +### Fixed + +- `Any::from()` was erasing guarded errors + ## 5.1.0 - 2025-09-06 ### Added diff --git a/proofs/router.php b/proofs/router.php index fb66df5..f3af72f 100644 --- a/proofs/router.php +++ b/proofs/router.php @@ -10,6 +10,7 @@ Any, Respond, Collect, + Pipe, }; use Innmind\Http; use Innmind\Url\Url; @@ -322,6 +323,60 @@ static function($assert, $url, $method, $wrongMethod, $protocolVersion, $status) }, ); + yield proof( + 'Any::from() should not override user errors', + given( + Set::of(...Http\Method::cases()), + Set::of(...Http\Method::cases()), + Set::of(...Http\ProtocolVersion::cases()), + ), + static function($assert, $method, $other, $protocolVersion) { + $in = Http\ServerRequest::of( + Url::of('/foo'), + $method, + $protocolVersion, + ); + $expected = new Exception; + $router = Router::of( + Any::from(Sequence::of( + Pipe::new() + ->{$method->name}() + ->handle(static fn() => Attempt::error($expected)), + Pipe::new() + ->{$other->name}() + ->handle(static fn() => Attempt::error(new Exception)), + )), + ); + + $assert->same( + $expected, + $router($in)->match( + static fn($response) => $response, + static fn($error) => $error, + ), + ); + + $router = Router::of( + Any::from(Sequence::of( + Pipe::new() + ->{$method->name}() + ->handle(static fn() => Attempt::error($expected)), + Pipe::new() + ->{$other->name}() + ->handle(static fn() => Attempt::error(new Exception)), + )), + ); + + $assert->same( + $expected, + $router($in)->match( + static fn($response) => $response, + static fn($error) => $error, + ), + ); + }, + ); + yield proof( 'Respond::with()', given( diff --git a/src/Any.php b/src/Any.php index c65d72a..b75dbd4 100644 --- a/src/Any.php +++ b/src/Any.php @@ -73,12 +73,12 @@ static function($previous, $component, $continuation) use ($beacon, $request, $i // If the new error is the beacon then it means the // previous error was a guarded one and it will try to - // recover from it. So we can stop iterating other + // recover from it. So we can stop iterating over other // components. return $result->match( static fn() => $continuation->stop($result), static fn($e) => match ($e) { - $beacon => $continuation->stop($result), + $beacon => $continuation->stop($previous), default => $continuation->continue($result), }, ); diff --git a/src/Pipe/Endpoint.php b/src/Pipe/Endpoint.php index bca2ec1..d0ec63c 100644 --- a/src/Pipe/Endpoint.php +++ b/src/Pipe/Endpoint.php @@ -58,7 +58,7 @@ public function handle(callable $handle): Component { return $this ->toComponent() - ->pipe(Handle::via($handle)); + ->feed(Handle::via($handle)); } #[\NoDiscard] diff --git a/src/Pipe/Forward/Method.php b/src/Pipe/Forward/Method.php index 324a5eb..cef88cd 100644 --- a/src/Pipe/Forward/Method.php +++ b/src/Pipe/Forward/Method.php @@ -54,7 +54,7 @@ public function handle(callable $handle): Component { return $this ->toComponent() - ->pipe(Handle::via($handle)); + ->feed(Handle::via($handle)); } public function spread(): Method\Spread diff --git a/src/Pipe/Method/Endpoint.php b/src/Pipe/Method/Endpoint.php index 09892bd..2490a6a 100644 --- a/src/Pipe/Method/Endpoint.php +++ b/src/Pipe/Method/Endpoint.php @@ -62,7 +62,7 @@ public function handle(callable $handle): Component { return $this ->toComponent() - ->pipe(Handle::via($handle)); + ->feed(Handle::via($handle)); } #[\NoDiscard]