web-dev-qa-db-fra.com

Symfony2 Controller n'acceptera pas d'exception

C'est le gestionnaire d'itinéraire pour mon action de suppression. Cela fonctionne bien tant que l'élément n'a pas d'associations.

public function projectDeleteAction()
{
    try {
        $request = $this->get('request');
        $my_id = $request->query->get('id');

        $em = $this->get('doctrine.orm.entity_manager');

        $item = $em->find('MyBundle:Main', $my_id);

        $em->remove($item);
        $em->flush();

        $info = $item->getName();
        $result = 0;
    }
    catch (Exception $e) {
        $info = toString($e);
        $result = -1;
    }

    return $this->render('MyBundle:Main:response.xml.twig',
            array('info' => $info, 'result' => $result ));
}

J'ai déjà résolu l'erreur d'essayer de supprimer un élément avec des associations, mais grâce à ce processus, le "flush" lançait une exception PDOException. J'ai essayé plusieurs façons de le détecter, mais il semble s'être coincé dans Symfony2, puis il répond par une erreur HTTP 500. Existe-t-il un moyen pour que Symfony2 ne détecte pas cela afin que je puisse le gérer? Ceci est une réponse XML utilisant AJAX et je préférerais donc simplement envoyer un code d'erreur comme indiqué ci-dessus.

25
sleeves

Essayez de changer Exception\Exception si vous n'avez pas spécifié PDOException en tant que Exception dans une instruction use. PHP essaie de trouver \YourNamespaceWithController\Exception au lieu de \Exception.

78
Josef

Il vaut mieux attraper l'exception que vous voulez vraiment attraper. Dans cet exemple, il s'agit probablement de Doctrine/DBAL/DBALException et/ou de Doctrine/DBA/DBAException.

Ainsi

catch (Doctrine\DBAL\DBALException $e) {
  $result = -1;
};

Je recommanderais de faire quelque chose comme:

    } catch (\Exception $e) {
        switch (get_class($e)) {
            case 'Doctrine\DBAL\DBALException':
                echo "DBAL Exception<br />";
                break;
            case 'Doctrine\DBA\DBAException':
                echo "DBA Exception<br />";
                break;
            default:
                throw $e;
                break;
        }
    }

Cela intercepte les exceptions de base de données et si, pour une raison quelconque, une autre exception se produit, elle est à nouveau renvoyée dans Symfony2.

9
Rudy Broersma

Je devais faire ce qui suit, ce qui pourrait aider certains utilisateurs;

try{
    $this->doctrine->em->persist($user);
    $this->doctrine->em->flush();
}catch(Exception $e){
    if($e->getPrevious()->getCode() == 23505){
        //handle duplicate error, 23505 is for postgres, 23000 is mysql unique constraint.    
    }
}
0
Jurgen