Skip to content

Commit

Permalink
Merge pull request #2 from peteonline/feat-rest-error-handling
Browse files Browse the repository at this point in the history
Feat rest error handling
  • Loading branch information
stuffaboutpete committed May 23, 2014
2 parents 8850a60 + 5ec3c3b commit 075d6ee
Show file tree
Hide file tree
Showing 18 changed files with 585 additions and 307 deletions.
99 changes: 46 additions & 53 deletions Application/Dispatchable/Mvc.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace PO\Application\Dispatchable;

use PO\Application;
use PO\Application\IErrorHandler;
use PO\Application\IExceptionHandler;
use PO\Application\IDispatchable;
use PO\Application\Dispatchable\Mvc\Controller;
use PO\Application\Dispatchable\Mvc\IControllerIdentifier;
Expand All @@ -29,7 +29,7 @@
*
* Exceptions that occur in identifying
* a route or whilst dispatching are
* handled by an IErrorHandler object.
* handled by an IExceptionHandler object.
*/
class Mvc
implements IDispatchable
Expand All @@ -47,16 +47,16 @@ class Mvc
private $controllerIdentifier;

/**
* Error handler
* Exception handler
*
* An instance of IErrorHandler which
* An instance of IExceptionHandler which
* is provided with any exception thrown
* whilst identifying or dispatching
* a controller or template
*
* @var PO\Application\IErrorHandler
* @var PO\Application\IExceptionHandler
*/
private $errorHandler;
private $exceptionHandler;

/**
* Response object
Expand All @@ -65,7 +65,7 @@ class Mvc
* this object is dispatched.
* It is set with controller
* content or provided to the
* error handler if required.
* exception handler if required.
*
* @var PO\Http\Response
*/
Expand All @@ -77,17 +77,17 @@ class Mvc
* Provide a location to find controllers
* both in terms of file system and namespace
*
* @param string $controllerPath Root directory where controllers are found
* @param string $controllerBaseNamespace Root namespace where controllers are found
* @param string $controllerPath Root directory where controllers are found
* @param string $controllerBaseNamespace Root namespace where controllers are found
* @return PO\Application\Dispatchable\Mvc self
*/
public function __construct(
IControllerIdentifier $controllerIdentifier,
IErrorHandler $errorHandler = null
IExceptionHandler $exceptionHandler = null
)
{
$this->controllerIdentifier = $controllerIdentifier;
$this->errorHandler = $errorHandler;
$this->exceptionHandler = $exceptionHandler;
}

/**
Expand All @@ -97,7 +97,7 @@ public function __construct(
* both to the provided response object.
*
* Note that no exceptions are thrown if
* instance of IErrorHandler is provided
* instance of IExceptionHandler is provided
* to constructor.
*
* @param PO\Http\Response $response A response object which will be set during dispatch
Expand All @@ -116,29 +116,22 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
{

// Save the response object
// for use in error handling
// for use in exception handling
$this->response = $response;

// Set up the error handler
// if provided
if ($this->hasErrorHandler()) {
$this->errorHandler->setup($response);
register_shutdown_function([$this->errorHandler, 'handleError']);
}

// Attempt to identify a controller,
// template and path variables from
// our controller identifier. Pass
// any exception to the error handler
// if provided, else rethrow.
// any exception to the exception
// handler if provided, else rethrow.
try {
$this->controllerIdentifier->receivePath($_SERVER['REQUEST_URI']);
$controller = $this->controllerIdentifier->getControllerClass();
$templatePath = $this->controllerIdentifier->getTemplatePath();
$pathVariables = $this->controllerIdentifier->getPathVariables();
} catch (\Exception $exception) {
if ($this->hasErrorHandler()) {
$this->handleException($exception);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -154,8 +147,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
Exception::CONTROLLER_CLASS_DOES_NOT_EXIST,
"Class name: $controller"
);
if ($this->hasErrorHandler()) {
$this->handleException($exception, 500);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -177,8 +170,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
Exception::CONTROLLER_CLASS_IS_NOT_CONTROLLER,
'Class name: ' . get_class($controller)
);
if ($this->hasErrorHandler()) {
$this->handleException($exception, 500);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -193,8 +186,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
// to run it via inversion of control.
if (!method_exists($controller, 'dispatch')) {
$exception = new Exception(Exception::CONTROLLER_HAS_NO_DISPATCH_METHOD);
if ($this->hasErrorHandler()) {
$this->handleException($exception, 500);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -211,8 +204,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
Exception::CONTROLLER_TEMPLATE_DOES_NOT_EXIST,
"Template path: $templatePath"
);
if ($this->hasErrorHandler()) {
$this->handleException($exception, 500);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -227,8 +220,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
$exception = new Exception(
Exception::NO_CONTROLLER_CLASS_OR_TEMPLATE_COULD_BE_IDENTIFIED
);
if ($this->hasErrorHandler()) {
$this->handleException($exception, 404);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response, 404);
} else {
$response->set404();
}
Expand All @@ -249,8 +242,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
? 'Array ' . implode(', ', $pathVariables)
: gettype($pathVariables))
);
if ($this->hasErrorHandler()) {
$this->handleException($exception, 500);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -271,7 +264,7 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
// Run the controller via the
// inversion of control container
// whilst handling any exceptions
// if error handler is available
// if exception handler is available
try {
if (is_object($controller)) {
$ioCContainer->call(
Expand All @@ -283,8 +276,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
}
} catch (\Exception $exception) {
ob_end_clean();
if ($this->hasErrorHandler()) {
$this->handleException($exception);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -308,8 +301,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
? 'Array ' . implode(', ', $templateVariables)
: gettype($templateVariables))
);
if ($this->hasErrorHandler()) {
$this->handleException($exception, 500);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -333,8 +326,8 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)
if (file_exists($templatePath)) include $templatePath;
} catch (\Exception $exception) {
ob_end_clean();
if ($this->hasErrorHandler()) {
$this->handleException($exception);
if ($this->hasExceptionHandler()) {
$this->handleException($exception, $response);
return;
} else {
throw $exception;
Expand All @@ -355,36 +348,36 @@ public function dispatch(Response $response, IoCContainer $ioCContainer)

/**
* Returns whether this object has
* an instance of IErrorHandler
* an instance of IExceptionHandler
*
* @return boolean
*/
private function hasErrorHandler()
private function hasExceptionHandler()
{
return isset($this->errorHandler);
return isset($this->exceptionHandler);
}

/**
* Passes provided exception to
* error handler and ensures that
* the response object is set to
* the given response code or 500
* exception handler and ensures
* that the response object is set
* to the given response code or 500
*
* @param Exception $exception The exception to handle
* @param int|string $recommendedResponseCode optional The response code to set the response to
* @return null
*/
private function handleException(\Exception $exception, $recommendedResponseCode = null)
private function handleException(\Exception $exception, Response $response, $responseCode = 500)
{
// Should we recieve a message?
$method = 'set' . (isset($recommendedResponseCode) ? $recommendedResponseCode : 500);
$method = 'set' . $responseCode;
try {
$this->errorHandler->handleException($exception, $recommendedResponseCode);
$this->exceptionHandler->handleException($exception, $response, $responseCode);
} catch (\Exception $exception) {
$this->response->$method($exception->getMessage() . $exception->getTraceAsString());
}
if (!$this->response->isInitialised()) {
$this->response->$method();
$this->response->$method($exception->getMessage() . $exception->getTraceAsString());
}
}

Expand Down
Loading

0 comments on commit 075d6ee

Please sign in to comment.