1010use Psr \Http \Message \ServerRequestInterface ;
1111use Psr \Http \Message \StreamFactoryInterface ;
1212use Respect \Parameter \Resolver ;
13+ use Respect \Rest \Handlers \ErrorHandler ;
14+ use Respect \Rest \Handlers \ExceptionHandler ;
15+ use Respect \Rest \Handlers \StatusHandler ;
1316use Respect \Rest \Routes \AbstractRoute ;
1417use Throwable ;
1518
19+ use function in_array ;
1620use function is_a ;
1721use function rawurldecode ;
1822use function rtrim ;
@@ -50,7 +54,7 @@ final class DispatchContext implements ContainerInterface
5054 private string $ effectivePath = '' ;
5155
5256 /** @var array<int, AbstractRoute> */
53- private array $ sideRoutes = [];
57+ private array $ handlers = [];
5458
5559 private Resolver |null $ resolver = null ;
5660
@@ -138,9 +142,10 @@ public function response(): ResponseInterface|null
138142 }
139143
140144 $ route = $ this ->route ;
145+ $ isHandler = in_array ($ route , $ this ->handlers , true );
141146
142147 try {
143- $ errorHandler = $ this ->prepareForErrorForwards ($ route );
148+ $ errorHandler = $ isHandler ? null : $ this ->prepareForErrorForwards ();
144149 $ preRoutineResult = $ this ->routinePipeline ()->processBy ($ this , $ route );
145150
146151 if ($ preRoutineResult !== null ) {
@@ -164,20 +169,25 @@ public function response(): ResponseInterface|null
164169 }
165170
166171 $ processedResult = $ this ->routinePipeline ()->processThrough ($ this , $ route , $ rawResult );
167- $ errorResponse = $ this ->forwardErrors ($ errorHandler , $ route );
168172
169- if ($ errorResponse !== null ) {
170- return $ errorResponse ;
173+ if (!$ isHandler ) {
174+ $ errorResponse = $ this ->forwardErrors ($ errorHandler );
175+
176+ if ($ errorResponse !== null ) {
177+ return $ errorResponse ;
178+ }
171179 }
172180
173181 return $ this ->finalizeResponse ($ processedResult );
174182 } catch (Throwable $ e ) {
175- $ exceptionResponse = $ this ->catchExceptions ($ e , $ route );
176- if ($ exceptionResponse === null ) {
177- throw $ e ;
183+ if (!$ isHandler ) {
184+ $ exceptionResponse = $ this ->catchExceptions ($ e );
185+ if ($ exceptionResponse !== null ) {
186+ return $ exceptionResponse ;
187+ }
178188 }
179189
180- return $ exceptionResponse ;
190+ throw $ e ;
181191 }
182192 }
183193
@@ -193,10 +203,10 @@ public function setRoutinePipeline(RoutinePipeline $routinePipeline): void
193203 $ this ->routinePipeline = $ routinePipeline ;
194204 }
195205
196- /** @param array<int, AbstractRoute> $sideRoutes */
197- public function setSideRoutes (array $ sideRoutes ): void
206+ /** @param array<int, AbstractRoute> $handlers */
207+ public function setHandlers (array $ handlers ): void
198208 {
199- $ this ->sideRoutes = $ sideRoutes ;
209+ $ this ->handlers = $ handlers ;
200210 }
201211
202212 public function setResponder (Responder $ responder ): void
@@ -229,18 +239,18 @@ public function get(string $id): mixed
229239 }
230240
231241 /** @return callable|null The previous error handler, or null */
232- protected function prepareForErrorForwards (AbstractRoute $ route ): callable |null
242+ protected function prepareForErrorForwards (): callable |null
233243 {
234- foreach ($ route -> sideRoutes as $ sideRoute ) {
235- if ($ sideRoute instanceof Routes \Error ) {
244+ foreach ($ this -> handlers as $ handler ) {
245+ if ($ handler instanceof ErrorHandler ) {
236246 return set_error_handler (
237247 static function (
238248 int $ errno ,
239249 string $ errstr ,
240250 string $ errfile = '' ,
241251 int $ errline = 0 ,
242- ) use ($ sideRoute ): bool {
243- $ sideRoute ->errors [] = [$ errno , $ errstr , $ errfile , $ errline ];
252+ ) use ($ handler ): bool {
253+ $ handler ->errors [] = [$ errno , $ errstr , $ errfile , $ errline ];
244254
245255 return true ;
246256 },
@@ -251,32 +261,32 @@ static function (
251261 return null ;
252262 }
253263
254- protected function forwardErrors (callable |null $ errorHandler, AbstractRoute $ route ): ResponseInterface |null
264+ protected function forwardErrors (callable |null $ errorHandler ): ResponseInterface |null
255265 {
256266 if ($ errorHandler !== null ) {
257267 set_error_handler ($ errorHandler );
258268 }
259269
260- foreach ($ route -> sideRoutes as $ sideRoute ) {
261- if ($ sideRoute instanceof Routes \Error && $ sideRoute ->errors ) {
262- return $ this ->forward ($ sideRoute );
270+ foreach ($ this -> handlers as $ handler ) {
271+ if ($ handler instanceof ErrorHandler && $ handler ->errors ) {
272+ return $ this ->forward ($ handler );
263273 }
264274 }
265275
266276 return null ;
267277 }
268278
269- protected function catchExceptions (Throwable $ e, AbstractRoute $ route ): ResponseInterface |null
279+ protected function catchExceptions (Throwable $ e ): ResponseInterface |null
270280 {
271- foreach ($ route -> sideRoutes as $ sideRoute ) {
272- if (!$ sideRoute instanceof Routes \Exception ) {
281+ foreach ($ this -> handlers as $ handler ) {
282+ if (!$ handler instanceof ExceptionHandler ) {
273283 continue ;
274284 }
275285
276- if (is_a ($ e , $ sideRoute ->class )) {
277- $ sideRoute ->exception = $ e ;
286+ if (is_a ($ e , $ handler ->class )) {
287+ $ handler ->exception = $ e ;
278288
279- return $ this ->forward ($ sideRoute );
289+ return $ this ->forward ($ handler );
280290 }
281291 }
282292
@@ -287,18 +297,18 @@ protected function forwardToStatusRoute(ResponseInterface $preparedResponse): Re
287297 {
288298 $ statusCode = $ preparedResponse ->getStatusCode ();
289299
290- foreach ($ this ->sideRoutes as $ sideRoute ) {
300+ foreach ($ this ->handlers as $ handler ) {
291301 if (
292- $ sideRoute instanceof Routes \Status
293- && ($ sideRoute ->statusCode === $ statusCode || $ sideRoute ->statusCode === null )
302+ $ handler instanceof StatusHandler
303+ && ($ handler ->statusCode === $ statusCode || $ handler ->statusCode === null )
294304 ) {
295305 $ this ->hasStatusOverride = true ;
296306
297307 // Run routine negotiation (e.g. Accept) before forwarding,
298308 // since the normal route-selection phase was skipped
299- $ this ->routinePipeline ()->matches ($ this , $ sideRoute , $ this ->params );
309+ $ this ->routinePipeline ()->matches ($ this , $ handler , $ this ->params );
300310
301- $ result = $ this ->forward ($ sideRoute );
311+ $ result = $ this ->forward ($ handler );
302312
303313 // Preserve the original status code on the forwarded response
304314 return $ result ?->withStatus($ statusCode );
0 commit comments