thephpleague / route

Fast PSR-7 based routing and dispatch component including PSR-15 middleware, built on top of FastRoute.
http://route.thephpleague.com
MIT License
651 stars 126 forks source link

How can I assign controller to errors http ? #331

Open ericktucto opened 1 year ago

ericktucto commented 1 year ago

I like send a Response if Method Not Found o route Not Found

example:

<?php
$router
  ->group("/dashboard", function () { /* code */ })
  ->set500([ErrorController::class, "handle500"])
  ->setStrategy(new ApplicationStrategy());
class ErrorController
{
  public function handle500($request)
  {
    return Response::html("<h1>Sorry, exists problem!</<h1>");
  }
  // handle401, handle401, handle402, handle403, handle404, handle419, handle429, handle503
}
$router
  ->group("/api/v1", function () { /* code */ })
  ->set500([ErrorJsonController::class, "handle500"])
  ->setStrategy(new JsonStrategy());
class ErrorJsonController
{
  public function handle500($request)
  {
    return Response::json(["message" => "Sorry, exists problem!"]);
  }
  // handle401, handle401, handle402, handle403, handle404, handle419, handle429, handle503
}

or

<?php
$router
  ->group("/dashboard", function () { /* code */ })
  ->setErrorHandle(ErrorController::class)
  ->setStrategy(new ApplicationStrategy());
class ErrorController
{
  // use dynamic
  public function handle500($request)
  {
    return Response::html("<h1>Sorry, exists problem!</<h1>");
  }
  // handle401, handle401, handle402, handle403, handle404, handle419, handle429, handle503
}
$router
  ->group("/api/v1", function () { /* code */ })
  ->setErrorHandle(ErrorJsonController::class)
  ->setStrategy(new JsonStrategy());
class ErrorJsonController
{
  // use dynamic
  public function handle500($request)
  {
    return Response::json(["message" => "Sorry, exists problem!"]);
  }
  // handle401, handle401, handle402, handle403, handle404, handle419, handle429, handle503
}
bertramakers commented 1 year ago

You need to implement a custom strategy (you can extend the existing ApplicationStrategy or JsonStrategy), and implement or override the getThrowableHandler() method in your custom strategy.

This method should return an implementation of MiddlewareInterface that forwards the given ServerRequestInterface to the next RequestHandlerInterface, wrapped it in a try/catch so that it can catch any Throwables and convert them to responses.

Take a look at the implementation in JsonStrategy for an example: https://github.com/thephpleague/route/blob/5.x/src/Strategy/JsonStrategy.php#L64-L98

You can then use your custom strategy on a route group, a single route, or the whole router depending on your needs. In your case I think you'll need to create 2 custom strategies, one for HTML pages and one for JSON endpoints, and assign them to the right routes/groups like you did with the default ApplicationStrategy and JsonStrategy in your example.

Disclaimer: I'm not the author/maintainer of this package.