Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default exception handler #54

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
39 changes: 38 additions & 1 deletion src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,9 @@ public function execute(Route $route, Request $request): self
}
}
}
} catch (\Throwable $e) {
} catch (\Throwable $e) {;
$errorHandled = false;

foreach ($groups as $group) {
foreach (self::$errors as $error) { // Group error hooks
/** @var Hook $error */
Expand All @@ -586,6 +588,7 @@ public function execute(Route $route, Request $request): self
try {
$arguments = $this->getArguments($error, $values, $request->getParams());
\call_user_func_array($error->getAction(), $arguments);
$errorHandled = true;
} catch (\Throwable $e) {
throw new Exception('Error handler had an error', 0, $e);
}
Expand All @@ -602,11 +605,23 @@ public function execute(Route $route, Request $request): self
try {
$arguments = $this->getArguments($error, $values, $request->getParams());
\call_user_func_array($error->getAction(), $arguments);
$errorHandled = true;
} catch (\Throwable $e) {
throw new Exception('Error handler had an error', 0, $e);
}
}
}

if (!$errorHandled) {
$response = $this->getResource('response');
$response->setStatusCode(500);
$response->json([
'message' => $e->getMessage(),
'stacktrace' => $e->getTrace()
]);
\fwrite(STDERR, "\033[31mException: " . $e->getMessage() . "\033[0m\n");
\fwrite(STDERR, "Stacktrace: \n" . $e->getTraceAsString() . "\n");
}
}

return $this;
Expand Down Expand Up @@ -728,26 +743,48 @@ public function run(Request $request, Response $response): self
}
}
} catch (\Throwable $e) {
$errorHandled = false;
foreach (self::$errors as $error) { // Global error hooks
/** @var Hook $error */
if(in_array('*', $error->getGroups())) {
self::setResource('error', function() use ($e) {
return $e;
});
\call_user_func_array($error->getAction(), $this->getArguments($error, [], $request->getParams()));
$errorHandled = true;
}
}

if (!$errorHandled) {
$response->setStatusCode(500);
$response->json([
'message' => $e->getMessage(),
'stacktrace' => $e->getTrace()
]);
\fwrite(STDERR, "\033[31mException: " . $e->getMessage() . "\033[0m\n");
\fwrite(STDERR, "Stacktrace: \n" . $e->getTraceAsString() . "\n");
}
}
} else {
$errorHandled = false;
foreach (self::$errors as $error) { // Global error hooks
/** @var Hook $error */
if(in_array('*', $error->getGroups())) {
self::setResource('error', function() {
return new Exception('Not Found', 404);
});
\call_user_func_array($error->getAction(), $this->getArguments($error, [], $request->getParams()));
$errorHandled = true;
}
}

if (!$errorHandled) {
$response->setStatusCode(404);
$response->json([
'message' => 'Not Found'
]);
\fwrite(STDERR, "\033[31mException: " . 'Route not found' . "\033[0m\n");
}
}

return $this;
Expand Down
4 changes: 0 additions & 4 deletions tests/e2e/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,6 @@ public function call(string $method, string $path = '', array $headers = [], arr

$responseHeaders['status-code'] = $responseStatus;

if ($responseStatus === 500) {
echo 'Server error('.$method.': '.$path.'. Params: '.json_encode($params).'): '.json_encode($responseBody)."\n";
}

return [
'headers' => $responseHeaders,
'body' => $responseBody
Expand Down
12 changes: 12 additions & 0 deletions tests/e2e/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,16 @@ public function testRedirect()
$response = $this->client->call(Client::METHOD_GET, '/redirect');
$this->assertEquals('Hello World!', $response['body']);
}

public function testException()
{
$response = $this->client->call(Client::METHOD_GET, '/exception');
$this->assertEquals(500, $response['headers']['status-code']);
}

public function testHandledException()
{
$response = $this->client->call(Client::METHOD_GET, '/handledException');
$this->assertEquals('Handled Exception.', $response['body']);
}
}
20 changes: 20 additions & 0 deletions tests/e2e/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@
$response->redirect('/');
});

App::get('/exception')
->inject('response')
->action(function($response) {
/** @var Utopia/Response $response */
throw new Exception('Exception!');
});

App::get('/handledException')
->inject('response')
->action(function($response) {
/** @var Utopia/Response $response */

App::error(function ($error, $response) {
/** @var Utopia/Response $response */
$response->send('Handled Exception.');
}, ['error', 'response']);

throw new Exception('Exception!');
});

$request = new Request();
$response = new Response();

Expand Down