Last active
September 19, 2018 13:02
-
-
Save ervinne13/534d63773cb061a7683fd954e6c19fa9 to your computer and use it in GitHub Desktop.
Separating render from exceptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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