Something that I see all over the place in the WordPress ecosystem is using false
as an indicator that a plugin failed to work as-expected. This nasty habit is something I want to squash once and for all. This post will discuss a much better WordPress alternative to using false
– the WP_Error
object.
The Problem With Returning False For Errors
false does not mean that something is wrong. It means something is not true. Think about it – how does false actually signify “this function failed to complete the task it set out to-do”? It doesn’t, not really. false is a vague response that sometimes means that something went wrong. This is easier to see if you think about the get_option function in WordPress. This function will return the value of something from the database, and if something goes wrong it returns false. Now, what happens if you actually stored the option as false in the database? How can you tell if you retrieved false
from the database, or if get_option
simply failed to fetch the value? In the case of get_option
, it converts everything to a string
so instead of receiving false
, you would receive "0"
. All because this function defaults to returning false
when something goes wrong. Yuck.
Another issue with returning false
when there is an error, is that it is vague. It doesn’t actually explain what went wrong, it just says false
. This means the only way you can determine what happened is by doing some debugging. Very little data can actually be logged in a logger, and production friendly debugging methods like Query Monitor have no way of offering more insight into what went wrong.
Finally, what happens if there’s multiple reasons why a function would fail? Since it just returns false
, there’s no way to add logic that allows you to do different things based on why a function failed. For example, let’s say you have this function:
This function will return false
if the function was called too early, and the $wp_query
global is not set. It will also return false if there no posts to get the last post from. These are two distinct reasons why this function would fail, and in the current version, you have no way of knowing why your function isn’t working. I would personally want to log when this function is called before $wp_query
is set, since that is probably a bug in my code. In the case of where the function fails because there’s no posts, I would want to handle in some different manner, perhaps by displaying a default post, or simply displaying no content at all.
Enter The WP_Error Object
All of the problems mentioned above can be resolved using a WP_Error
object instead of false
. Unlike false
, WP_Error
is intended to explicitly communicate that something went wrong. You can easily check to see if something is an error with the is_wp_error()
function, and it provides a lot more information about the error.
For example, let’s take the exact same function, and re-write it to use WP_Error
instead of false
:
In the modified version, this function will return a WP_Error
object. This object will return a list of things that went wrong when calling the function, complete with helpful messages, an error code, and any arbitrary data that can help with debugging. Much better.
This also enforced a cleaner, easier to-read pattern for our function call. that looks something like this:
- Validate the function
- Bail early if something went wrong
- Otherwise execute the function and return the result
In our example, it’s only possible for the returned WP_Error
object to have a single error, but you can add as many errors as you want using add_error
as shown above. This allows you to return multiple reasons why the function fails to run.
Checking for Errors
You can check to see if your function returned an error using the is_wp_error()
function. As the name implies, this function basically checks to see if a variable is an instance of WP_Error
, and returns true
or false
based on that.
For example, you could execute the example function above, and check to see if it’s an error like so:
From there, you can go even further, and do different things based on what error message you received, like so:
Logging Errors With Underpin
Once you start writing your functions using WP_Error
instead of false
, you can start adding errors to a debug log to make troubleshooting your plugin much, much easier. The Underpin framework has a built-in logging utility for plugins, and it is tightly integrated with the WP_Error
object. If you’re using underpin, you can instruct it to log a WP_Error
directly with underpin()->logger()->log_wp_error()
.
Conclusion
With one simple change – you can make your plugin easier to extend, easier to debug, and just generally easier to understand. A lot of older WordPress functions still use false
, but that’s because they have to for backwards compatibility reasons. If you look at newer functions you’ll see that they almost always use WP_Error
instead. I encourage you to follow this pattern, and make your plugins easier to use moving forward.
Leave a Reply