Php 捕获不同的异常类型

Php 捕获不同的异常类型,php,symfony,exception-handling,try-catch,Php,Symfony,Exception Handling,Try Catch,我有一个非常简单的函数来检查捆绑包中是否存在实体: public function checkExists($bundle, $val) { try{ $this->em->getRepository($bundle.':'.$val); }catch (MappingException $e){ return false; } return true; } 因此,我有以下情况: Input

我有一个非常简单的函数来检查捆绑包中是否存在实体:

public function checkExists($bundle, $val)
{
    try{
       $this->em->getRepository($bundle.':'.$val);
    }catch (MappingException $e){
        return false;
    }

    return true;
}
因此,我有以下情况:

Input                        |    Expected    |    Actual
'AppBundle', 'Company'       |    true        |    true
'AppBundle', 'NONEXISTANT'   |    false       |    false (MappingException caught)
'NONEXISTANT', 'Company'     |    false       |    500 (ORMException not caught)
'NONEXISTANT', 'NONEXISTANT' |    false       |    500 (ORMException not caught)

所以我发现问题在于抛出了不同的异常,但是对于一部分不存在的情况,我怎么能返回false呢?在symfony中是否有捕获异常的“常规”方法,如
catch(Exception$e)
with
use symfony\Component\Config\Definition\Exception\Exception没有捕捉到它。

有几件事要做: 您可以首先捕获所有异常,然后以不同方式处理每个异常:

public function checkExists($bundle, $val)
{
    try{
       $this->em->getRepository($bundle.':'.$val);
    } catch (\Exception $e){ // \Exception  is the global scope exception
        if ($e instanceof MappingException || $e instanceof ORMException) {
            return false;
        } 
        throw $e; //Rethrow it if you can't handle it here.
    }

    return true;
}
另一种情况是有多个捕获:

 public function checkExists($bundle, $val)
{
    try{
       $this->em->getRepository($bundle.':'.$val);
    } catch (MappingException $e){
       return false;
    } catch (ORMException $e) {
       return false;
    }  //Other exceptions are still unhandled.

    return true;
}
如果您使用的是PHP 7.1+,那么您还可以执行以下操作:

public function checkExists($bundle, $val)
{
    try{
       $this->em->getRepository($bundle.':'.$val);
    } catch (MappingException | ORMException $e){ //Catch either MappingException or ORMException 
       return false;
    }  //Other exceptions are still unhandled.

    return true;
}

创建异常侦听器并在那里处理它们

class ExceptionListener
{
    /** @var LoggerInterface */
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $e = $event->getException();
        if ($e instanceof ValidationException) {
            $this->logger->notice('Validation error' , $e->getViolations());
        } elseif ($e instanceof DomainException) {
            $this->logger->warning('Exception ' . get_class($e) , ['message' => $e->getMessage()]);
            $event->setResponse(
            new JsonResponse(['error' => $this->translator->trans($e->getOutMessage())], 400)
            );
        } else {
            $event->setResponse(
                new JsonResponse(['error' => $this->translator->trans('http.internal_server_error')], 500)
            );
        }
    }
}
更新服务.yml

  app.exception_listener:
    class: Application\Listeners\ExceptionListener
    arguments: ['@domain.logger']
    tags:
      - { name: kernel.event_listener, event: kernel.exception }
关于听众和事件的进一步阅读


我不确定您是否应该在应用程序发布时创建引发映射异常的情况。

您确实不想依赖异常处理这类内容。看看条令的元数据。特别是:$em->getClassMetadata($entityClassName);