[wp-hackers] Why WP_Error Sucks
Ryan McCue
lists at rotorised.com
Wed Jul 25 06:47:52 UTC 2012
Andrew Nacin wrote:
> You also mention the idea of putting try/catch inside of the plugin API —
> that would be terribly slow, and defeats the purpose of forcing exceptions
> on developers. Congratulations, a plugin developer didn't code for an
> exception because they knew core would catch it and issue a wp_die()
> message, like that error would ever happen anyway. No thanks.
To clarify what I said in the blog post: the idea of putting them inside
do_action/apply_filters would be to avoid calling wp_die() and instead
letting just that callback fail.
At the moment, a lot of developers forget about WP_Error (at least, in
the plugin audits I've done). This means that it actually causes a
warning (attempting to access object as array, e.g.) or worse, gives bad
data.
> 1. As return codes. Often, WP_Error is used when the error is not
> "exceptional." It enables you to pass multiple errors, and also extra data.
Definitely agree. There are plenty of places where it does make sense to
use WP_Error instead of an exception. I stereotyped all errors in my
blog post to be the type suiting exceptions, because there are a lot
that are. For those that aren't, WP_Error should be used instead,
although in some cases, a more specific class might be more useful.
As for the multiple errors/extra data, both of those are possible with
exceptions. Exceptions are still normal objects.
> 2. As legitimate errors where exceptions could be used, but shouldn't be.
> This kind of factors into return codes. I personally do not find a failed
> HTTP request to be "exceptional" that, if uncaught, should result in a
> fatal error.
I also agree here, but only for certain cases:
- cURL/fsockopen/Stream errors should be exceptions. These are things
which should be raised, as they are a failure regardless of use case
- HTTP errors (i.e. non-2xx status codes) should not be exceptions,
unless the caller specifically asks for them to be. For example,
Requests [0] has a `throw_for_error()` method on the response object;
Mike suggested an 'exception' option, which would also work great.
The reason for this is because it's dependent on the caller as to
whether one of these statuses is a failure mode.
> Wrapping all of this in a try/catch would be nice. (I think relying on
> exceptions to bubble is lazy; we'd be handling these all within that
> routine.)
It's less about being lazy and more about handling it where it makes
sense, rather than having to handle it at every stage.
>
> However, two major problems with this. One,
> wp-admin/includes/update-core.php is copied over during a core update and
> executed by the currently installed version. Can't throw a WP_Exception
> when WP_Exception doesn't exist yet.
Why not include a mock WP_Exception within that? We already have mock
functions in wp-admin/load-scripts.php and wp-admin/load-styles.php.
On top of that, we could just use Exception itself. The functions that
have it available could use WP_Exception, and the other functions could
use Exception; the calling code could then catch all of them with `catch
(Exception $e)`
> The second problem is that PHP doesn't have finally blocks.
I do agree with that, and I'm not a fan of that, however they are
working on that (it looks likely that it'll make it into 5.5, and
possibly 5.4). That doesn't make much of a difference to us, but you can
fake it in the few cases where you actually need it:
try {
$fp = fopen('readme.txt');
some_function_that_throws_an_exception($fp);
fclose($fp);
}
catch (Exception $e) {
fclose($fp);
throw $e;
}
It does involve duplication, but it's still possible, and I think it's
used infrequently enough that it's not too much of an issue.
> I'm not saying there isn't a single use in WordPress for a WP_Exception. I
> know for a fact there are some, but I also don't think there are enough
> examples where an exception would be oh-just-so-much-better than error
> objects to justify a paradigm change. As it is, WordPress is getting
> complicated (almost too complicated) in certain areas, and it'll only serve
> to hurt theme developers, designers, and many weaker plugin authors the
> more "by the book" we become.
WordPress is well-known throughout a lot of the PHP community for being
fairly horrible from a PHP standpoint. This has been changing as WP gets
modernised and I think part of that is embracing the facilities we have
in PHP.
I also think this will benefit plugin authors, especially the weaker
ones. A lot of them don't bother to check `is_wp_error()`. Exceptions on
the other hand make it very obvious when an error has occurred, and are
much less obscure than a "cannot use object of type WP_Error as array"
error.
Theme developers/designers should never need to handle that. Exceptions
don't make sense for any of the template tags (e.g.), only the more
low-level stuff.
> And of course, plugin authors can already use exceptions if they wanted to.
And they should, hence why I wrote about converting WP_Error to
exceptions now. I already do this myself. :)
> Write your own HTTP API wrapper that throws exceptions — come on, you're a
> programmer, do what programmers do: make a personal, convoluted abstraction
> layer. :-)
Actually, my plan was to write a wrapper for Requests [0] to make it
expose a WP_Http-like API, including WP_Error support (so basically, in
the other direction). Convolution FTW! :D
Thanks for the detailed response!
[0]: http://requests.ryanmccue.info/
--
Ryan McCue
<http://ryanmccue.info/>
More information about the wp-hackers
mailing list