Silex: error handlers for specific types of exceptions

Is it possible in Silex to use an error handler based on which exception is thrown?

I know that this is possible with a single exception handler and a switch statement in the class name for the generated exception, but for me it seems that the "Silex" method is cleaner but does not work.

Here is how I could expect it to work

<?php // Handle access denied errors $app->error(function (\App\Rest\Exception\AccessDenied $e) { $message = $e->getMessage() ?: 'Access denied!'; return new Response($message, 403); }); // Handle Resource not found errors $app->error(function (\App\Rest\Exception\ResourceNotFound $e) { $message = $e->getMessage() ?: 'Resource not found!'; return new Response($message, 404); }); // Handle other exception as 500 errors $app->error(function (\Exception $e, $code) { return new Response($e->getMessage(), $code); }); 

The problem is that when I throw a ResourceNotFound exception in my controller, the error handler associated with AccessDenied is executed

Fatal error allowed: argument 1 passed to {clos} () must be an instance of App \ Rest \ Exception \ AccessDenied, an instance of App \ Rest \ Exception \ ResourceNotFound specified

Is this achievable differently, or should I just populate everything in a handler that works with general exceptions and include the type of exception thrown?

PS: I know the $app->abort() method, but I prefer to work with exceptions

+4
source share
2 answers

EDIT: This feature has now become the core of Silex!


This is currently not possible. Right now you will have to either have one handler with the switch statement, or many handlers with if ($e instanceof MyException) each.

I like the idea, but it can be implemented using reflection. It would be great if you could create a new ticket for the tracker or even work with the patch if you are interested.

Hurrah!

+5
source

Another solution that I use in my projects:

 class ProcessCallbackException extends Exception { public function __construct(\Closure $callback, $message = "", Exception $previous = null) { parent::__construct($message, 0, $previous); $this->callback = $callback; } public $callback; } class AccessDeniedException extends ProcessCallbackException { public function __construct($message = null) { $f = function() { return app()->redirect('/login'); }; parent::__construct($f, $message); } } # Handle your special errors $app->error(function (\Exception $e, $code) { if ($e instanceof ProcessCallbackException) { /** @var ProcessCallbackException $callbackException */ $callbackException = $e; return call_user_func($callbackException->callback); } else return null; }); 
0
source

Source: https://habr.com/ru/post/1403102/


All Articles