Как я могу ловить ошибки и исключения в Symfony2/Silex?
Я хотел бы отлавливать ошибки и исключения в моем приложении Silex, чтобы обернуть их в пользовательский ответ JSON, который всегда будет возвращаться клиентам. Я нашел три основных метода:
$app->error()
Symfony\Component\Debug\ErrorHandler::register();
Symfony\Component\Debug\ExceptionHandler::register();
Хотя я могу ловить исключения контроллера с помощью error()
Я терплю неудачу с ошибками php - они всегда заканчиваются в xdebug. Я также не понимаю, как error()
а также ExceptionHandler::register()
взаимодействовать друг с другом - мне нужны оба? Как я могу убедиться, что мой error()
ответ JSON?
У меня есть следующий пример кода прямо сейчас:
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class Router extends Silex\Application
{
function __construct() {
parent::__construct();
// routes
$this->match('/{context}', array($this, 'handler'));
// error handler
$this->error(function(\Exception $e, $code) {
return $this->json(array("error" => $e->getMessage()), $code);
});
}
function handler(Request $request, $context) {
// throw new \Exception('test'); // exception- this is caught
$t = new Test(); // error- this is not caught
return 'DONE';
}
}
Symfony\Component\Debug\ErrorHandler::register();
$app = new Router();
$app->run();
2 ответа
С ErrorHandler:: register (); вы можете ловить свои ошибки как исключения
пример
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\Debug\ErrorHandler;
///bla bla bla some code
//catch all errors and convert them to exceptions
ErrorHandler::register();
try {
//for example error happens here
trigger_error( 'OH MY GOD, I AM ON FIRE' );
} catch ( \Exception $e ) {
//for debugging you can do like this
$handler = new ExceptionHandler();
$handler->handle( $e );
/*
* ExceptionHendler class comments
* It is mostly useful in debug mode to replace the default PHP/XDebug
* output with something prettier and more useful.
* so i suggest to create json response
* and replace this code $handler = new ExceptionHandler();
* $handler->handle( $e );
*/
return new JsonResponse(
array(
'status' => 'error',
'message' => $e->getMessage()
)
);
}
с Silex вы можете сделать следующее
ErrorHandler::register();
//register an error handler
$app->error(function ( \Exception $e, $code ) use ($app) {
//return your json response here
$error = array( 'message' => $e->getMessage() );
return $app->json( $error, 200 );
});
Я сталкиваюсь с этим случаем сегодня и нахожу способ связать фатальную ошибку с Silex.
Во-первых, вам нужно связать обработчик исключений с Silex:
$app->error(function (\Exception $exception, $code) {
// Something that build a nice \Symfony\Component\HttpFoundation\Response. This part is up to you.
$response = MyExceptionFormatter::format($exception, $code);
// A Silex exception handler must return a Response.
return $response;
});
Теперь мы используем Symfony Debug Component для преобразования наших ошибок.
// Convert simple errors into nice Exception, automaticaly handled by Silex.
Symfony\Component\Debug\ErrorHandler::register();
// Now, the hard part, handle fatal error.
$handler = Symfony\Component\Debug\ExceptionHandler::register($app['debug']);
$handler->setHandler(function ($exception) use ($app) {
// Create an ExceptionEvent with all the informations needed.
$event = new Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent(
$app,
$app['request'],
Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST,
$exception
);
// Hey Silex ! We have something for you, can you handle it with your exception handler ?
$app['dispatcher']->dispatch(Symfony\Component\HttpKernel\KernelEvents::EXCEPTION, $event);
// And now, just display the response ;)
$response = $event->getResponse();
$response->sendHeaders();
$response->sendContent();
//$response->send(); We can't do that, something happened with the buffer, and Symfony still return its HTML.
});