it-swarm.com.de

Eigene Ausnahmen abfangen

Ich habe ein Paket mit meiner eigenen Exception erstellt, aber beim Versuch, eine Exception abzufangen, ist ein schwerwiegender Fehler aufgetreten: Ungefangene Exception . Dies ist nur der Fall, wenn die Methode mit throw von add_action( 'init', array( $this, 'wp_some_method' ) ); übergeben wird. Beispiel:

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

Auf dem Bildschirm angezeigt:

Versuchen

__Konstrukteur

Und: Schwerwiegender Fehler: Nicht erfasste Ausnahme 'Ausnahme'

2

Ihre Ausnahme wird nicht vom try {} catch () {} -Block abgefangen, da sie nicht im try catch -Block abgelegt wird. Dies zeigt einen Mangel an Verständnis für asynchrone Ereignisse und das WordPress-Hook/Action/Event-System.

Die Methoden Ihres Objekts werden an den Init-Aktionshook angehängt und ausgelöst, wenn der Init-Hook ausgelöst wird, nicht, wenn das Objekt erstellt wird und nicht, wenn sie angehängt werden.

z.B.

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!

Ihre Methode wird beim Erstellen Ihres Objekts nicht aufgerufen. Es ist an das init-Ereignis angehängt, wird aber nicht aufgerufen, gerade weil das 'init'-Ereignis noch nicht stattgefunden hat. Das init-Ereignis tritt lange nach der Ausführung Ihrer try {} catch-Anweisung auf.

Daher wären diese eher angebracht:

  • füge einen try catch in die Klassenmethoden ein (am besten)
  • Wirf keine Ausnahmen in Funktionen, die an Hooks/Events gebunden sind (noch besser)
  • wirf die Ausnahme in eine neue Methode, die nicht die von dir angehängte ist, damit du sie in einen Versuchsfang einfügen kannst. (Okay, erfordert eine gute Trennung von Bedenken und Abstraktion.)
  • fügen Sie einen globalen Fehlerbehandler hinzu (hackisch, raten Sie dringend davon ab, es wird mehr Zeit in Anspruch nehmen als es wert ist, möglicherweise werden andere Ausnahmen abgefangen, die Sie nie beabsichtigt haben).

Andernfalls gibt es keinen vernünftigen, logischen und vernünftigen Grund, warum die Codezeile throw new \Exception im try catch-Block wie oben ausgeführt werden sollte, ohne dass Sie sie absichtlich manuell aufrufen, wie Sie es in Ihrem Test getan haben.

5
Tom J Nowell