Skip to main content

Working with the WP_Error class

Published ago
Updated ago
7 min read
Warning

This article was written in 2014 👴🏼. Most of the tips here are not valid anymore and I don't recommend using any of the snippets displayed here.

I'm keeping this article here for historical reasons and to remind myself how much I've improved over the years.

Only cosmetic changes were made to this article.

Sometimes when we are coding a new feature… Actually, every time we are coding a new feature we need to know what it's happening, specifically if something it's not working the way we want to. That's the reason I tend to display lots of messages in my development environments. Even if it's not an error.

But sometimes it is an error, and when that happens it's always better to treat it like one. A simple message might not be enough, maybe we need to log it, maybe we need to stop the execution of the page. Maybe we need to use WP_Error.

In WordPress, we have a special class to work with errors, WP_Error. it is a pretty simple class that helps us track and log error messages, let's say we have a contact form with two fields, Name and Email, of course we want to make sure our visitors enter only valid email addresses and if they don't, we use WP_Error to let them know.

The setup

I have a simple form with only two fields, when the user submits that form, the data will be sent through $_POST, I will attach an action to process the form and validate the data, like this:

1function mah_custom_shortcode( $atts, $content = null ) {
2 ob_start();
3?>
4 <form action="" id="mah_custom_form" method="post">
5 <p>
6 <label for="name"><?php _e( 'Name' ); ?></label><br>
7 <input type="text" id="name" name="mah_name">
8 </p>
9 <p>
10 <label for="email"><?php _e( 'Email' ); ?></label><br>
11 <input type="text" id="email" name="mah_email">
12 </p>
13 <?php wp_nonce_field( 'mah_nonce_action', 'mah_nonce_field' ); ?>
14 <input type="submit" class="primary" name="mah_submit" value="<?php _e( 'Submit' ); ?>">
15 </form>
16<?php
17 return apply_filters( 'mah_custom_shortcode', ob_get_clean() );
18}
19add_shortcode( 'mah_custom_form', 'mah_custom_shortcode' );
20

This is pretty straightforward, I'm just creating a shortcode to use in my posts, that shortcode will display the form, now let's see the process function:

1function mah_process_function() {
2 if ( isset( $_POST[ 'mah_submit' ] ) && wp_verify_nonce( $_POST[ 'mah_nonce_field' ], 'mah_nonce_action' ) ) {
3 // Start validation and save it in a variable
4 $email = is_email( $_POST[ 'mah_email' ]) // Check if it's a valid address
5 ? sanitize_email( $_POST[ 'mah_email' ] ) // Is valid
6 : new WP_Error( 'mah_email_error', __( 'Please enter a valid email address' ) );
7
8 // Check if there was an error
9 if ( is_wp_error( $email ) ) {
10 wp_die( $email->get_error_message(), 'mah_form_error' );
11 }
12 }
13
14}
15add_action( 'init', 'mah_process_function' );
16
  • First we check if the value for mah_submit is set, that means the form has been submitted, then we verify the nonce field to make sure it is still valid.
  • We use is_email to validate the email address, this function is provided by wordpress and returns true if it's valid.
  • If the email was valid, we assign that value to the $email variable, after using sanitize_email to clean the address just in case.
  • If the email was not valid, the value we assign to the $email variable will be a new error object. - mah_email_error is the code we use for this specific error, when we work with multiple errors it's a good idea to give them a code. - Then we can give specify the message that will be use when we display this error to the user.

Now, we have created our error, but we still need to display it to the user.

Luckily, the WP_Error class also provides a function for this: is_wp_error. This function checks the data passed and if it's an error object it returns true. After that, it's easy to use wp_die to display the error message.

Working with several error messages

This piece of code was useful if we only need to display one error message at a time, but what if I wanted to validate the Name field as well and display both messages in the same screen?

I could use the same approach, but then I would have two different error objects, I just want one, so I need to have ready before validating the data.

1function mah_process_function() {
2 if ( isset( $_POST[ 'mah_submit' ] ) && wp_verify_nonce( $_POST[ 'mah_nonce_field' ], 'mah_nonce_action' ) ) {
3 // Start error object
4 $mah_error = new WP_Error();
5
6 // Validate email
7 if ( is_email( $_POST[ 'mah_email' ] ) ) { // Check if it's a valid address
8 $email = sanitize_email( $_POST[ 'mah_email' ] ); // Is valid
9 // Add new error to the object
10 } else {
11 $mah_error->add( 'mah_email_error', __( 'Please enter a valid email address' ) );
12 }
13
14 // Validate name
15 if ( ! is_numeric( $_POST[ 'mah_name' ] ) ) { // no numeric values allowed
16 $name = sanitize_text_field( $_POST[ 'mah_name' ] ); // clean it up
17 } else {
18 $mah_error->add( 'mah_name_error', __( 'Name can not be a number') );
19 }
20
21
22 // Check if there was an error
23 if ( is_wp_error( $mah_error ) ) {
24 wp_die( $mah_error, __( 'Form Error' ) );
25 }
26 }
27
28}
29

While it's pretty similar, id does have a few differences, let's break it down:

  • Now I declare $mah_error at the beginning, this will be empty since I haven't added any errors yet.
  • $mah_error->add: Instead of returning new WP_Error I simply use the add method to insert a new error to the list, I do the same thing with the next field.
  • Even if I declared $mah_error as a WP_Error object at the beginning, it will not be treated as an error until I add at least one error to the list, so is_wp_error will still be valid if empty.
  • wp_die can except either a string like in the previous example, or the full WP_Error object, if I send the object it will display all the errors in the list.

This was just a simple introduction to the WP_Error class, I recommend reading through the codex and try to use it as often as possible and check out the rest of methods, there's really useful stuff in there.