Symfony 4,如何 return 正确地从服务 Class 错误 500 服务器

Symfony 4, how return properly a error 500 server from a service Class

从服务 class,如何管理异常和 return 错误 500? 例如,我有一个服务 class 'A' 从另一个服务 Class 'B' 调用。服务内容 'A' 是:

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 var 设置了一个错误的值,该过程将停止(如我所愿),并且在我使用此服务构建 symfony http 网页的情况下,会显示一个空白页面和我的消息,但这页面获得状态 200(不是 500 'internal server error')。

return 服务异常的 good/properly 方法是什么?

在 'service called from a controller used only for REST web service' 上下文 and/or 中 'service called from another service' 上下文 and/or 中是否有全局(symfony?oop php?)方法正确管理错误异常=] ,更传统地说,在 'service called from a classical http controller' 上下文中 ? (奖金:"service called from a custom Command Class" 中的 and/or)

也许我完全误解了这个问题,但我会说:从您的服务中抛出异常。

但是:如果你能正确处理它,你只会捕获到一个异常。在你的情况下,它看起来好像你不能在你的服务中处理它,所以你让它冒泡到适当的 Symfony 组件(在控制台命令、控制器或 Rest 端点之间不同)。

服务不应设置 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
    }
}