Catch own Exceptions

I build some package with my own Exception but when I try to catch a exception I got fatal error: Uncaught exception. This situation is only when method with throw is passed by add_action( 'init', array( $this, 'wp_some_method' ) );
Example:

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

Displayed on the screen:

Read More

try

__constructor

And:
Fatal error: Uncaught exception ‘Exception’

Related posts

1 comment

  1. Your exception isn’t caught by the try{} catch(){} block, because it isn’t thrown inside the try catch block. This demonstrates a lack of understanding of asynchronous events and the WordPress hook/action/event system.

    The methods of your object are attached to the init action hook, and are thrown when the init hook is fired, not when the object is created, and not when they’re attached.

    e.g.

    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!
    

    Your method is not called when your object is created. It’s attached to the init event yes, but it is not called, precisely because the ‘init’ event hasn’t happened yet. The init event happens long after your try{} catch statement runs.

    So instead, these would be more appropriate:

    • add a try catch in the class methods ( best )
    • Don’t throw exceptions in functions attached to hooks/events ( even better )
    • throw the exception in a new method that isn’t the method you attached so you can add in a try catch ( okay, requires good separation of concerns and abstraction )
    • add a global error handler ( hackish, strongly advise against, will take more time than its worth, may catch other exceptions that you never intended to catch )

    Otherwise there is no rational, logical, common sense reason why the line of code that says throw new Exception should be executed inside the try catch block as you have above without you purposefully calling it manually as you did in your test.

Comments are closed.