Symfony 4, как правильно вернуть 500 ошибку сервера из класса обслуживания

Как управлять исключениями и возвращать ошибку 500 из класса Service?
Например, у меня есть класс обслуживания «A», вызванный из другого класса обслуживания «B». Содержание услуги «А»:

namespace App\Service;

use ...

class A
{
...
public static function foo(){

$tmp =  [];

// do some stuff

if(isOK($tmp)){
return $tmp;
}else{
// return 500 with message
}
}

private static function isOK($tmp){
// do some stuff
}
}

Я попробовал это:

namespace App\Service;

use ...

class A
{
...
public static function foo(){

$tmp =  [];

// do some stuff

if(isOK($tmp)){
return $tmp;
}else{
// return 500 with message
}
}

private static function isOK($tmp){
try{
if(...) throw new \Exception();
}catch (HttpException $e){
dump('not valid data $tmp var in ' . __FUNCTION__,500);
exit;
}
}
}

Но я не думаю, что я использую хороший способ. Если я намеренно установил неправильное значение переменной $ tmp, процесс будет остановлен (как я хочу), и в случае, когда я использую этот сервис для создания http-страницы Symfony http, с моим сообщением отображается пустая страница, но это страница получает статус 200 (не 500 «внутренняя ошибка сервера»).

Каков хороший / правильный способ возврата исключения из Сервиса?

Существует ли глобальный (symfony? Oop php?) Способ для правильного управления исключениями ошибок в контексте «служба, вызываемая из другой службы» и / или в «службе, вызываемой из контроллера, используемого только для контекста веб-службы REST» и / или, условно, в контексте «службы, вызываемой из классического контроллера http»? (бонус: и / или в «службе, вызываемой из пользовательского класса команд»)

0

Решение

Может быть, я полностью неправильно понял вопрос, но я бы сказал: выбросить исключение из вашей службы.

Но: вы только поймаете исключение, если сможете правильно с ним справиться. В вашем случае это выглядит так, как будто вы не можете справиться с этим в своей Службе, поэтому вы позволяете ему пузыриться к соответствующему компоненту Symfony (который отличается между консольной командой, контроллером или конечной точкой отдыха).

Служба не должна устанавливать код 500, так как не знает, в каком контексте она используется. Поэтому вы можете захотеть вызвать явное исключение ServiceException, перехватить его в вашем контроллере и преобразовать в нечто более полезное:

class A
{
public function foo(){
$tmp =  [];
if($this->isOK($tmp)){
return $tmp;
}
throw new ServiceException('Failed checking $tmp');
}

private function isOK($tmp){
return false;
}
}

class TestController
{
/**
* @var A
*/
protected $a;

public function fooAction() {
try {
$this->a->foo();
} catch (ServiceException $e) {
throw new HttpException(500, $e->getMessage())
}
}
}

Для Интернета и отдыха вы должны убедиться, что ваше исключение имеет правильный код, который затем будет использоваться для установки HTTP-кода.

Только код, который использует сервис, знает, как правильно обрабатывать Исключение. Поскольку код состояния не имеет значения в вашей консольной команде, вы не можете его перехватить.
Но в целом вы можете сказать, что это не лучшая практика, поскольку вам, возможно, придется выполнить некоторую очистку (закрыть соединения, закрыть дескрипторы файлов, записать журнал ошибок), прежде чем Исключение будет передано на следующий уровень кода.

Пример для консоли:

class MyCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$a = new A();
try {
$this->a->foo();
} catch (ServiceException $e) {
// write to log file
$io->error('Service failed: ' . $e->getMessage());
return;
}
// do more stuff
}
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector