Silent Failure with the WOOF_Silent class

One of the nicest aspects of coding with the MasterPress API is the way it allows developers to drill down into nested object properties via chained property access and method calls. Frequently, you can access these nested properties and methods using just a single line of code:

Example 1: Resizing a photo field in a details field set, via nested property and method access

If you’re familiar with writing object-oriented code, however, the example above may beg the question: “What happens when either of the “about-us” page, the details field set or the photo field don’t exist – will the code fail with an error in the middle somewhere?”

MasterPress handles these scenarios with a special WOOF_Silent class, which is used throughout the API to represent “doesn’t exist”, “empty”,”false”, or some other error condition. WOOF_Silent is essentially like a vacuum – it swallows up most attempts to call methods on it, access properties of it, iterate over it, or attempts to echo it, causing them to essentially “do nothing.

Importantly, methods throughout the API are written to return a WOOF_Silent object when something isn’t found, with a descriptive error about why it wasn’t found, rather than returning false or null. Consider a pseudocode outline of the “page” method above:

Example 2: A semi-pseudocode outline of the WOOF::page method

So in example 1, if the page didn’t exist, we’d have a WOOF_Silent object at the point before we access the “details” field. Taking what we said above about “swallowing” access to subsequent objects, the end result for our call is simply nothing – that is, an empty string gets echoed to the template.

The concept of silent failure would be familiar to you if you’ve ever written JavaScript code with jQuery. jQuery returns an “empty set” when you try to select an element in the DOM that doesn’t exist, thereby swallowing any subsequent calls in the chain, without throwing an error. This is a key aspect of jQuery that allows you to write far more concise code than the equivalent pure JavaScript code, since you don’t need to constantly test for null results – it’s often okay if the code simply doesn’t do anything.

Finding the point of failure – the debug method

We’ve established that WOOF_Silent prevents errors occurring in our code when we try to access, echo, or iterate over things that don’t exist. But how do we find out what went wrong when we expected a different result?

All objects in the MasterPress API contain a debug method which outputs a representation of the internal state of the object, for debugging purposes. The WOOF_Silent object’s debug method helps you work through problem-code by outputting the error condition at the point the chained property access started to fail. Since all objects support the debug method, we can simply add it to the end of the chain, to see a good or bad result.

So, if you were to implement Example 1 but find you’re getting no output, you could add a debug call on the end like so:

Example 3: Calling the debug method

This might output something like the following, if there was no page in your site with the slug “about-us”:

Cannot find page with id or slug 'about-us'

Clearly, this should be a great help to discover why your code isn’t living up to your lofty expectations 🙂

This is an important technique to remember, since debugging with other methods like var_dump and print_r don’t always work as well as the debug method.

Testing for existence with if statements – the exists method.

There’s one big “gotcha” about the way that most API methods return WOOF_Silent objects – any object in PHP evaluates to true when used as a boolean expression, such as the condition of an if statement. Consider the following well-intentioned code:

Example 4: Checking for existence - the wrong way

The code looks okay – we only want to boast about our About page if the page exists. But what you’ll find is that the message will always be output, even when we don’t have an About Us page. If our “page” method returned “false” or “null” when the post didn’t exist we’d be fine, but our API returns WOOF_Silent objects in cases like this.

WOOF_Silent has an exists method, which can help us out here, and even make our code read a little better:

Example 5: Checking for existence - the right way

This will give us the correct behaviour, only boasting about the page if it’s truly there.

It’s important to note that this relies on the fact that all other objects in our API also implement the exists method to return true when they represent a valid object. Most other objects do return a true result for this method, with one notable exception; WOOF_File objects will check for the existence of the file in the file system, so you can follow a similar pattern, and write code like:

Example 6: Checking for the existence of a file

As you can see, the exists pattern is very useful and is consistent with our expectations if you were to simply read the code like it’s written in English.

Quick-assignment inside if statements

We stated above that for most objects in the API, the exists method returns a true result to indicate that they are not silent objects. In actual fact, objects that do “exist” will return themselves instead of returning boolean true. Keeping in mind that WOOF_Silent returns boolean false, this allows us to write if statements that lookup something, assign a variable to that something, and also check if that something exists. Let’s consider the “long” form first:

Example 7: Pre-assigning the page

We set the $about variable first, and then check for it’s existence. If it does exist, we output a link to it. We can rewrite this code with quick-assignment like so:

Example 8: Quick-assigning the page

Here we assign the variable from the result of exists, which we just said will return that object itself, or false otherwise. Put another way the whole expression evaluates to a non-false result if the post exists, or a definite false if it doesn’t exist.

This style of coding will undoubtedly be polarising – some developers won’t find this intuitive enough to decipher again later, but those who like to shortcut everything will probably love it. Your call…

Latest From the Blog

MasterPress 1.4.1 is now available

27th May 2024

This update addresses backwards compatibility issues that were introduced in the previous update. There were some edge cases where PHP 7 had issues and it didn’t work at all on PHP 5.6. We have now changed it so that the PHP 8 compatibility changes will now only affect PHP 8 and will be more thorough… 

Plugin Requirements

MasterPress requires a minimum of WordPress version 4.9, MySQL 5.6, and PHP version 5.6.20.

We also recommend that PHP is configured to use a memory limit of 64MB per request (128MB may be required for sites with higher complexity).

This plug-in is not compatible with the hosted service.

Three AM