web-dev-qa-db-fra.com

Attraper ses propres exceptions

Je construis un paquet avec ma propre exception, mais lorsque j'essaie d'attraper une exception, j'ai l'erreur fatale: Exception non capturée . Cette situation se produit uniquement lorsque la méthode avec projection est passée par add_action( 'init', array( $this, 'wp_some_method' ) );. Exemple:

class SomeClass {
    public function __construct() {
        add_action( 'init', array( $this, 'wp_some_method' ) );
        echo '__constructor<br />';
    }
    function some_method(){
        throw new \Exception('some message');
    }
    function wp_some_method( $post_type ){
        throw new \Exception('Some second error'); 
    }
}
try{
    echo 'try <br />';
    $o = new SomeClass();
    //$o->some_method(); - this throw exception correct

} catch (\Exception $ex) {
    echo $ex->getMessage();
}

Affiché à l'écran:

essayez

__constructor

Et: Erreur fatale: exception non capturée 'Exception'

2

Votre exception n'est pas interceptée par le bloc try {} catch () {}, car elle n'est pas renvoyée à l'intérieur du bloc try. Cela démontre un manque de compréhension des événements asynchrones et du système de connexion/action/événements de WordPress.

Les méthodes de votre objet sont attachées au hook d’action init, et sont levées lorsque le hook d’initialisation est activé, pas lorsque l’objet est créé, ni quand ils sont attachés.

par exemple.

class SomeClass {
    public function __construct() {
        // when the init action/event happens, call the wp_some_method
        add_action( 'init', array( $this, 'wp_some_method' ) );
    }
    function wp_some_method( $post_type ){
        throw new \Exception('error'); 
    }
}
try{
    // great, no exceptions where thrown while creating the object
    $o = new SomeClass();    
} catch (\Exception $ex) {
    echo $ex->getMessage();
}

// a small period of time later somewhere in WP Core...

do_action( 'init' ); // a method we attached to the init hook threw an exception, but nothing was there to catch it!

Votre méthode n'est pas appelée lors de la création de votre objet. Il est attaché à l'événement init oui, mais il n'est pas appelé, précisément parce que l'événement 'init' n'a pas encore eu lieu. L'événement init survient longtemps après l'exécution de votre instruction try {}.

Donc, au lieu de cela, ces derniers seraient plus appropriés

  • ajouter un essai dans les méthodes de classe (meilleur)
  • Ne lancez pas d'exceptions dans les fonctions attachées aux hooks/événements (encore mieux)
  • jetez l'exception dans une nouvelle méthode qui n'est pas la méthode que vous avez jointe afin de pouvoir l'ajouter à un catch try (d'accord, nécessite une bonne séparation des préoccupations et de l'abstraction)
  • ajouter un gestionnaire d'erreur global (hackish, fortement déconseillé, prendra plus de temps que nécessaire, peut intercepter d'autres exceptions que vous n'avez jamais eu l'intention de capturer)

Autrement, il n’existe aucune raison rationnelle, logique et logique selon laquelle la ligne de code indiquant throw new \Exception doit être exécutée dans le bloc catch catch comme ci-dessus sans que vous ne l’appeliez à dessein manuellement comme vous l’avez fait dans votre test.

5
Tom J Nowell