WordPress, filters, chain of responsibility

WordPress, filters and a chain of responsibility.

Theory

I have to filter a query response and have been adding small specialized classes to the WordPress posts_where filter.
WordPress hooks and actions are, in functions, an implementation of the chain of responsibility pattern of sort: each function/method hooking into an action or a filter will manipulate the same data in a chain following a priority order and transformed data will be output at the end.
What is missing, and this is my particular case, is the possibility to bail out of the chain should further processing become needless.
An example of this:

  add_filter('posts_where', 'filter_one', 1, 2);
  add_filter('posts_where', 'filter_two', 2, 2);
  add_filter('posts_where', 'filter_three', 3, 2);
  add_filter('posts_where', 'filter_four', 4, 2);

  function filter_one($where, WP_Query $query){
    global $post;

    $post = empty($post) ? false : $post;

    if(empty($post)) {
        return $where;
    }

    $should_return_nothing = query->get('post_type') == array('custom_post_type') && !current_user_can('edit_posts', $post->ID);

    if($should_return_nothing){
        // invalidate query
        $where .= ' AND 1=0';
    }

    return $where;
  }

  function filter_two($where, WP_Query $query){
    // further filtering...
  }

  function filter_three($where, WP_Query $query){
    // further filtering...
  }

  function filter_four($where, WP_Query $query){
    // further filtering...
  }

The first function, filter_one, is forcing zero posts to be returned and making the rest of the filters superfluous if a certain condition is verified.
Nonetheless the other filters, the one I set and the others that are hooking in posts_where, are going on consuming time and resources in the meanwhile.

A measure of control

I’ve modified the code to maintain a measure of control on my portion of the filters wrapping the posts_where filter and creating, in a common pattern, a sub-chain

add_filter('posts_where', 'my_posts_where', 10, 2);

function my_posts_where($where, WP_Query $query){
    try{
        return apply_filters('catching_posts_where', $where, $query);
    } catch (NoMatchesException $e){
        return $where .= ' AND 1 = 0';
    }
}

and will throw my custom exception to break the chain as soon as possibile and return no posts.

  add_filter('catching_posts_where', 'filter_one', 1, 2);
  add_filter('catching_posts_where', 'filter_two', 2, 2);
  add_filter('catching_posts_where', 'filter_three', 3, 2);
  add_filter('catching_posts_where', 'filter_four', 4, 2);

  function filter_one($where, WP_Query $query){
    global $post;

    $post = empty($post) ? false : $post;

    if(empty($post)) {
        return $where;
    }

    $should_return_nothing = query->get('post_type') == array('custom_post_type') && !current_user_can('edit_posts', $post->ID);

    if($should_return_nothing){
        throw new NoMatchesException();
    }

    return $where;
  }

  function filter_two($where, WP_Query $query){
    // further filtering...
  }

  function filter_three($where, WP_Query $query){
    // further filtering...
  }

  function filter_four($where, WP_Query $query){
    // further filtering...
  }

this way no further filter of mine will run.

This solution has little miles but works if a complex chain of stupid filters is in place; wrapping all of the filtering in one function would work the same but I am a fan of stupid objects and this solution allows for easy extension of the chain.
Further exception types/codes allow for more control to be added (I’d go with exception types).