2017-07-28 5 views
3

j'ai une fonction très simple de vérifier si une entité existe dans un paquet:Catch différents types d'exception

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

    return true; 
} 

J'ai donc les cas suivants:

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) 

Je vois que le problème est qu'il y a différentes exceptions jetées, mais comment pourrais-je retourner faux pour l'un des cas d'une partie inexistant? Existe-t-il un moyen "général" de capturer les exceptions dans symfony car catch (Exception $e) avec use Symfony\Component\Config\Definition\Exception\Exception; ne l'attrape pas.

+0

Copie possible de [Attraper plusieurs types d'exception dans un bloc catch] (https://stackoverflow.com/questions/8439581/catching-multiple-exception-types-in-one-catch-block) – jkucharovic

+1

Je ne veux pas compter sur des exceptions pour ce genre de choses. Jetez un oeil aux métadonnées de Doctrine. En particulier: $ em-> getClassMetadata ($ entityClassName); – Cerad

Répondre

3

Il y a deux choses à faire: Vous pouvez prendre toutes les exceptions tout d'abord, vous pouvez gérer chacun différemment:

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; 
} 

Alternatevely ont de multiples prises:

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; 
} 

Si vous re en utilisant PHP 7.1 + alors vous pouvez également faire:

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; 
} 
1

Créer une exception Listener et les gérer là.

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) 
      ); 
     } 
    } 
} 

Mise à jour services.yml

app.exception_listener: 
    class: Application\Listeners\ExceptionListener 
    arguments: ['@domain.logger'] 
    tags: 
     - { name: kernel.event_listener, event: kernel.exception } 

Pour en savoir plus sur les auditeurs et les événements https://symfony.com/doc/current/event_dispatcher.html

Je ne suis pas sûr que vous devez créer des situations qui jettent des exceptions de cartographie, lorsque votre application est expédiée.