wp_mail not running inside Cron

The wp_mail() function is not running when scheduled in a cron function. I have added the following function:

add_filter( 'cron_schedules', 'isa_add_every_one_minutes' );
function isa_add_every_one_minutes( $schedules ) {
    $schedules['every_sixty_seconds'] = array(
            'interval'  => 60,
            'display'   => __( 'Every 1 Minutes', 'textdomain' )
    );
    return $schedules;
}

// Schedule an action if it's not already scheduled
if ( ! wp_next_scheduled( 'isa_add_every_one_minutes' ) ) {
    wp_schedule_event( time(), 'every_sixty_seconds', 'isa_add_every_one_minutes' );
}

// Hook into that action that'll fire every three minutes
add_action( 'isa_add_every_one_minutes', 'only_debug_admin' );


function only_debug_admin(){
    $message = "Test message";

wp_mail( 'email@example.com', $message, $message );

update_option('default_role','customer');   
    }

When I run the cron manually via wp-control plugin, I receive a mail and wp-mail works fine. However, when the cron job is run. To debug, I add this line below the mail function:

update_option('default_role','customer'); 

I set the default role to subscriber in WordPress settings. On cron run, the setting gets updated to ‘customer’ but the mail is not received. On manually running the function, the mail is received. Any idea why this is happening?

2 Answers
2

This one is a bit of a puzzler. I was originally going to say you need to determine if there’s something wrong after the mail is sent since you’re getting the hit in the next operation. But then I re-read it and caught the part about the email being received when it’s run manually.

What you need to do is find out if there’s an error occurring. Since it’s not a manual process, that’s not quite straight forward; but there are ways to do it. This answer won’t specifically solve the problem you’re having, but it should give you way to determine what that issue actually is.

I would set up to catch any errors and then log them. You can do that by making sure WP is set up for debugging and to log any errors. Make sure the following is in your wp-config.php:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );

Now you can use WP’s error_log() function to write any errors to the log file.

wp_mail() returns a true|false boolean when run. If there are any errors, it will return false. So we can write to the log depending on the result.

So in your function, write the to the error log based on the returned result.

function only_debug_admin(){
    $message = "Test message";

    $wp_mail_result = wp_mail( 'email@example.com', $message, $message );

    if ( true === $wp_mail_result ) {
        error_log( 'wp_mail returned true!' );
    } else {
        error_log( 'wp_mail had an error!' );
    }
}

If wp_mail() errors (returns false), then you want to be able to capture any errors in phpMailer to see if that gives you any insight as to why.

add_action( 'phpmailer_init', 'my_log_phpmailer_init' );
function my_log_phpmailer_init( $phpmailer ) {
    error_log( print_r( $phpmailer, true ) );
}

Now when the cron runs, you can check the error log (/wp-content/debug.log) for what happened. If wp_mail() returned true, the issue is an email issue with either the sending host or the receiver (outside of WP). If it was false, review the errors from phpMailer (which should also be in the log).

This doesn’t solve your problem, but it gets you on track to figure out what it actually is.

Leave a Comment