Larvel api class exception handling
I have a Laravel 4.2 application with the following route:
Route::group(['prefix' => 'api/v1'], function()
{
Route::resource('service_logs', 'ServiceLogsController', [
'only' => ['index', 'store', 'show']
]);
});
The controller ServiceLogsController
extends from ApiController
which looks something like this:
class ApiController extends \BaseController {
protected $statusCode = 200;
public function getStatusCode()
{
return $this->statusCode;
}
public function setStatusCode($statusCode)
{
$this->statusCode = $statusCode;
return $this;
}
public function respondInternalError($message = 'Internal Error!')
{
return $this->setStatusCode(500)->respondWithError($message);
}
public function respondWithError($message)
{
return Response::json([
'error' => [
'message' => $message,
'status_code' => $this->getStatusCode()
]
], $this->getStatusCode());
}
// ...
}
What I would like to do, when an un-catch exception occurs, I want to call a method respondInternalError()
on mine ApiController
, so that the API consumer has a consistent response, not nothing or an html whoops
error.
For this, I tried to add the following code to my app/start/global.php
App::error(function(Exception $exception, $code)
{
Log::error($exception);
if (Request::is('api/*'))
{
App::make('ApiController')->respondInternalError('Uncaught api exception error occurred - ' . $exception->getMessage());
}
});
and to test it I tried to make a POST request to the following url: / api / v1 / service_logs / 123.
it won't work because this url is GET, so Laravel is throwing the correct one method not allowed exception
. However, he misses.
Any idea how to implement a catch all exception handler based on the controller class?
Update Slightly improved working "global" api exception handler
App::error(function(Exception $exception, $code)
{
Log::error($exception);
if (Request::is('api/*'))
{
$errorName = Symfony\Component\HttpFoundation\Response::$statusTexts[$code];
return App::make('ApiController')
->setStatusCode($code)
->respondWithError($errorName . ' error has occurred.');
}
});
On error, you get this now (testing is done in Chrome + Postman):
source to share