44
55namespace TinyBlocks \Http \ErrorHandler ;
66
7+ use Closure ;
78use Psr \Http \Message \ResponseInterface ;
89use Psr \Http \Message \ServerRequestInterface ;
910use Psr \Http \Server \MiddlewareInterface ;
1011use Psr \Http \Server \RequestHandlerInterface ;
1112use Psr \Log \LoggerInterface ;
1213use Throwable ;
14+ use TinyBlocks \Http \Code ;
1315use TinyBlocks \Http \ErrorHandler \Internal \DefaultErrorMiddlewareBuilder ;
1416use TinyBlocks \Http \ErrorHandler \Internal \ErrorLogger ;
1517use TinyBlocks \Http \ErrorHandler \Internal \ErrorOutcome ;
18+ use TinyBlocks \Http \ErrorHandler \Internal \Reporting \CompositeErrorReporter ;
19+ use TinyBlocks \Http \ErrorHandler \Internal \ResolvedRoute ;
20+ use TinyBlocks \Http \ErrorHandler \Reporters \SilentErrorReporter ;
1621
1722/**
1823 * PSR-15 middleware that captures exceptions thrown downstream, delegates to a consumer-provided
@@ -29,21 +34,33 @@ private function __construct(private ErrorOutcome $errorOutcome)
2934 * Builds an ErrorMiddleware from its configuration components.
3035 *
3136 * @param LoggerInterface|null $logger The logger to use for error logging, or <code>null</code> to disable logging.
37+ * @param Closure(ErrorPayload, ServerRequestInterface): string $message The rule settling the message the
38+ * response answers with.
3239 * @param ExceptionMappingTable $mappings The composed table that maps exceptions to error responses.
40+ * @param Closure(?MappedError, Code): ReportingPriority $priority The rule deriving a priority from the rule
41+ * that matched and the resolved status.
3342 * @param ErrorHandlingSettings $settings The settings controlling error display and logging behavior.
3443 * @param bool $fallbackOnUnmapped Whether to return a fallback response when no mapping matches.
44+ * @param ErrorReporter $reporter The reporter notified after the response is produced and logged. Defaults to
45+ * {@see SilentErrorReporter}, which forwards every report to no provider.
3546 * @return ErrorMiddleware The configured middleware instance.
3647 */
3748 public static function build (
3849 ?LoggerInterface $ logger ,
50+ Closure $ message ,
3951 ExceptionMappingTable $ mappings ,
52+ Closure $ priority ,
4053 ErrorHandlingSettings $ settings ,
41- bool $ fallbackOnUnmapped
54+ bool $ fallbackOnUnmapped ,
55+ ErrorReporter $ reporter = new SilentErrorReporter ()
4256 ): ErrorMiddleware {
4357 $ errorOutcome = new ErrorOutcome (
58+ message: $ message ,
4459 mappings: $ mappings ,
60+ priority: $ priority ,
4561 settings: $ settings ,
4662 errorLogger: ErrorLogger::from (logger: $ logger , settings: $ settings ),
63+ errorReporter: CompositeErrorReporter::create ()->with (reporter: $ reporter ),
4764 fallbackOnUnmapped: $ fallbackOnUnmapped
4865 );
4966
@@ -62,10 +79,21 @@ public static function create(): ErrorMiddlewareBuilder
6279
6380 public function process (ServerRequestInterface $ request , RequestHandlerInterface $ handler ): ResponseInterface
6481 {
82+ $ tags = ReportingTags::pending ();
83+ $ route = ResolvedRoute::pending ();
84+ $ routed = $ request
85+ ->withAttribute (ResolvedRoute::ATTRIBUTE_NAME , $ route )
86+ ->withAttribute (ReportingTags::ATTRIBUTE_NAME , $ tags );
87+
6588 try {
66- return $ handler ->handle ($ request );
89+ return $ handler ->handle ($ routed );
6790 } catch (Throwable $ exception ) {
68- return $ this ->errorOutcome ->resolve (request: $ request , exception: $ exception );
91+ return $ this ->errorOutcome ->resolve (
92+ tags: $ tags ,
93+ route: $ route ,
94+ request: $ routed ,
95+ exception: $ exception
96+ );
6997 }
7098 }
7199}
0 commit comments