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 ServiceLogsController
controller extends from ApiController
, which looks something like this cut down version:
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'd like to do is, when ever an un-caught exception occurs, I want to call the respondInternalError()
method on my ApiController
, so that the API consumer has a consistent response rather than nothing or html whoops
error.
To achieve this, I tried adding the following code in 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.
this will not work, because that URL is a GET url, so Laravel throws the correct method not allowed exception
. However, it's not getting caught.
Any idea how to implement a catch all exception handler per controller class basis?
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.');
}
});
When an error occurs, you get this now (testing done in Chrome + Postman):