Skip to content

Instantly share code, notes, and snippets.

@ervinne13
Last active September 19, 2018 13:02
Show Gist options
  • Save ervinne13/534d63773cb061a7683fd954e6c19fa9 to your computer and use it in GitHub Desktop.
Save ervinne13/534d63773cb061a7683fd954e6c19fa9 to your computer and use it in GitHub Desktop.
Separating render from exceptions
// app/Exceptions/Handlers.php
public function render($request, Exception $exception)
{
if ($this->exceptionToHttpResponseHandlerRouter->isHandleable($exception)) {
return $this->exceptionToHttpResponseHandlerRouter->handle($exception);
}
if (!$this->isApiCall($request)) {
return parent::render($request, $exception);
} else {
return $this->getJsonResponseForException($request, $exception);
}
}
// i have my own namespace for this lol, place wherever
class ExceptionToHttpResponseHandlerRouter
{
public function handle(ExceptionToHttpResponseHandledException $e): Response
{
$handler = $this->findHandler($e);
return $handler->handle($e);
}
public function isHandleable(Exception $e): bool
{
return ($e instanceof ExceptionToHttpResponseHandledException) && $this->isHandlerExisting($e);
}
private function isHandlerExisting(ExceptionToHttpResponseHandledException $e): bool
{
// we'll depend on the container to throw an EntryNotFoundException
// for us to know if there's a handler available for this exception
try {
$this->findHandler($e);
return true;
} catch (EntryNotFoundException $e) {
return false;
} catch (ReflectionException $e) {
return false;
}
}
public function findHandler(ExceptionToHttpResponseHandledException $e): ExceptionToResponseHandler
{
$handlerName = get_class($e);
return $this->findHandlerByName($handlerName);
}
public function findHandlerByName(string $handlerName): ExceptionToResponseHandler
{
return app($this->getHandlerBindingName($handlerName));
}
public function getHandlerBindingName(string $class)
{
return $class . 'Handler';
}
}
// beside ExceptionToHttpResponseHandlerRouter
// implement this in any exception you want to be "handleab
interface ExceptionToHttpResponseHandledException
{
// just a tag interface, nothing to see here
}
// in your providers, this will be your "map"
class ExceptionHandlerProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
$utility = app(ExceptionToHttpResponseHandlerRouter::class);
$ironmanExceptionHandler = $utility->getHandlerBindingName(IronmanException::class);
$this->app->bind($ironmanExceptionHandler, IronmanExceptionHandler::class);
// ... put other mappings here
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment