Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions features/utils-wp.feature
Original file line number Diff line number Diff line change
Expand Up @@ -1019,3 +1019,148 @@ Feature: Utilities that depend on WordPress code
"""
Test error message
"""

Scenario: WP_DEBUG=true displays errors on STDERR without --debug
Given a WP installation
And a wp-config.php file:
"""
<?php
define('DB_NAME', '{DB_NAME}');
define('DB_USER', '{DB_USER}');
define('DB_PASSWORD', '{DB_PASSWORD}');
define('DB_HOST', '{DB_HOST}');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
$table_prefix = 'wp_';

define('WP_DEBUG', true);

require_once(ABSPATH . 'wp-settings.php');
"""
And a test-notice.php file:
"""
<?php
WP_CLI::add_command( 'test-notice', function() {
trigger_error( 'Test notice message', E_USER_NOTICE );
echo 'Done';
} );
"""

When I try `wp --require=test-notice.php test-notice`
Then STDOUT should contain:
"""
Done
"""
And STDERR should contain:
"""
Test notice message
"""

Scenario: WP_DEBUG=false does not display errors on STDERR without --debug
Given a WP installation
And a wp-config.php file:
"""
<?php
define('DB_NAME', '{DB_NAME}');
define('DB_USER', '{DB_USER}');
define('DB_PASSWORD', '{DB_PASSWORD}');
define('DB_HOST', '{DB_HOST}');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
$table_prefix = 'wp_';

define('WP_DEBUG', false);

require_once(ABSPATH . 'wp-settings.php');
"""
And a test-notice.php file:
"""
<?php
WP_CLI::add_command( 'test-notice', function() {
trigger_error( 'Test notice message', E_USER_NOTICE );
echo 'Done';
} );
"""

When I run `wp --require=test-notice.php test-notice`
Then STDOUT should contain:
"""
Done
"""
And STDERR should not contain:
"""
Test notice message
"""

Scenario: WP_DEBUG=true with WP_DEBUG_DISPLAY=false does not display errors on STDERR
Given a WP installation
And a wp-config.php file:
"""
<?php
define('DB_NAME', '{DB_NAME}');
define('DB_USER', '{DB_USER}');
define('DB_PASSWORD', '{DB_PASSWORD}');
define('DB_HOST', '{DB_HOST}');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
$table_prefix = 'wp_';

define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', false);

require_once(ABSPATH . 'wp-settings.php');
"""
And a test-notice.php file:
"""
<?php
WP_CLI::add_command( 'test-notice', function() {
trigger_error( 'Test notice message', E_USER_NOTICE );
echo 'Done';
} );
"""

When I try `wp --require=test-notice.php test-notice`
Then STDOUT should contain:
"""
Done
"""
And STDERR should not contain:
"""
Test notice message
"""

Scenario: --debug flag always displays errors on STDERR regardless of WP_DEBUG
Given a WP installation
And a wp-config.php file:
"""
<?php
define('DB_NAME', '{DB_NAME}');
define('DB_USER', '{DB_USER}');
define('DB_PASSWORD', '{DB_PASSWORD}');
define('DB_HOST', '{DB_HOST}');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
$table_prefix = 'wp_';

define('WP_DEBUG', false);

require_once(ABSPATH . 'wp-settings.php');
"""
And a test-notice.php file:
"""
<?php
WP_CLI::add_command( 'test-notice', function() {
trigger_error( 'Test notice message', E_USER_NOTICE );
echo 'Done';
} );
"""

When I try `wp --debug --require=test-notice.php test-notice`
Then STDOUT should contain:
"""
Done
"""
And STDERR should contain:
"""
Test notice message
"""
13 changes: 11 additions & 2 deletions php/WP_CLI/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -1791,9 +1791,18 @@ static function () {
99
);

// Re-enable PHP error reporting to stderr if testing.
// Re-enable PHP error reporting to stderr if testing, but only when display_errors
// should be active (respecting WP_DEBUG and WP_DEBUG_DISPLAY the same way wp_debug_mode() does).
// We must explicitly enforce this after WP finishes loading, since wp-admin/includes/admin.php
// and other late-loading files may reset display_errors.
if ( getenv( 'BEHAT_RUN' ) ) {
$this->enable_error_reporting();
$show_errors = WP_CLI::get_config( 'debug' )
|| ( defined( 'WP_DEBUG' ) && WP_DEBUG && ( ! defined( 'WP_DEBUG_DISPLAY' ) || WP_DEBUG_DISPLAY ) );
if ( $show_errors ) {
$this->enable_error_reporting();
} else {
ini_set( 'display_errors', 0 ); // phpcs:ignore WordPress.PHP.IniSet.display_errors_Disallowed
}
}

WP_CLI::debug( 'Loaded WordPress', 'bootstrap' );
Expand Down
61 changes: 32 additions & 29 deletions php/utils-wp.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,43 +56,46 @@ function wp_debug_mode() {
}

error_reporting( E_ALL & ~E_DEPRECATED );
} else {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_reporting( E_ALL );

if ( defined( 'WP_DEBUG_DISPLAY' ) ) {
ini_set( 'display_errors', WP_DEBUG_DISPLAY ? 1 : 0 );
} elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_reporting( E_ALL );

if ( defined( 'WP_DEBUG_LOG' ) ) {
// @phpstan-ignore cast.useless
if ( in_array( strtolower( (string) WP_DEBUG_LOG ), [ 'true', '1' ], true ) ) {
$log_path = WP_CONTENT_DIR . '/debug.log';
// @phpstan-ignore function.alreadyNarrowedType
} elseif ( is_string( WP_DEBUG_LOG ) ) {
$log_path = WP_DEBUG_LOG;
} else {
$log_path = false;
}

if ( defined( 'WP_DEBUG_LOG' ) ) {
// @phpstan-ignore cast.useless
if ( in_array( strtolower( (string) WP_DEBUG_LOG ), [ 'true', '1' ], true ) ) {
$log_path = WP_CONTENT_DIR . '/debug.log';
// @phpstan-ignore function.alreadyNarrowedType
} elseif ( is_string( WP_DEBUG_LOG ) ) {
$log_path = WP_DEBUG_LOG;
} else {
$log_path = false;
}

if ( false !== $log_path ) {
ini_set( 'log_errors', 1 );
ini_set( 'error_log', $log_path );
}
if ( false !== $log_path ) {
ini_set( 'log_errors', 1 );
ini_set( 'error_log', $log_path );
}
} else {
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
}
} else {
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
}

// wp_doing_ajax() might not be available.
// @phpstan-ignore phpstanWP.wpConstant.fetch
if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
ini_set( 'display_errors', 0 );
}
// Respect WP_DEBUG and WP_DEBUG_DISPLAY: display errors when --debug is passed or
// WP_DEBUG is true (and WP_DEBUG_DISPLAY is not explicitly false).
$display_errors = WP_CLI::get_config( 'debug' )
|| ( defined( 'WP_DEBUG' ) && WP_DEBUG && ( ! defined( 'WP_DEBUG_DISPLAY' ) || WP_DEBUG_DISPLAY ) );

// wp_doing_ajax() might not be available.
// @phpstan-ignore phpstanWP.wpConstant.fetch
if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
$display_errors = false;
}

// XDebug already sends errors to STDERR.
ini_set( 'display_errors', function_exists( 'xdebug_debug_zval' ) ? false : 'stderr' );
if ( $display_errors ) {
ini_set( 'display_errors', function_exists( 'xdebug_debug_zval' ) ? false : 'stderr' );
} else {
ini_set( 'display_errors', 0 );
}
}
// phpcs:enable

Expand Down
Loading