web-dev-qa-db-ja.com

自分の例外をキャッチ

私は自分自身のExceptionを使っていくつかのパッケージをビルドしますが、例外をキャッチしようとすると致命的なエラーになりました:Uncaught exception。この状況は、throw付きのメソッドがadd_action( 'init', array( $this, 'wp_some_method' ) );によって渡された場合にのみ発生します。例:

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

画面に表示されます。

try

__コンストラクタ

そして:致命的エラー:捕捉されなかった例外 'Exception'

2

あなたの例外はtry {} catch(){}ブロックによってキャッチされません、なぜならそれはtry catchブロックの内側で投げられないからです。これは非同期イベントとWordPressフック/アクション/イベントシステムの理解不足を示しています。

あなたのオブジェクトのメソッドはinitアクションフックにアタッチされていて、initフックが起動されたときにスローされます。オブジェクトが作成されたときやアタッチされたときにはスローされません。

例えば.

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!

オブジェクトが作成されたときには、メソッドは呼び出されません。はい、それはinitイベントにアタッチされていますが、 'init'イベントがまだ起こっていないという理由だけで、呼び出されません。 initイベントは、try {} catchステートメントが実行されてからずっと後に発生します。

その代わりに、これらはより適切でしょう:

  • クラスメソッドにtry catchを追加する(最高)
  • フック/イベントに関連付けられた関数で例外をスローしないでください(さらに良いことです)。
  • あなたがアタッチしたメソッドではない新しいメソッドで例外を投げるので、try catchに追加することができます(大丈夫、懸念と抽象化の適切な分離が必要です)
  • グローバルエラーハンドラを追加します(ハッキング、強くお勧めします、その価値より長い時間がかかります、あなたがキャッチすることを意図しない他の例外をキャッチするかもしれません)

そうでなければ、throw new \Exceptionと言うコードの行が、あなたがテストのように意図的に手動でそれを呼び出さずに、上記のようにtry catchブロックの中で実行されるべきである合理的、論理的、常識的理由はありません。

6
Tom J Nowell