wppaste
WordPress

wp_trigger_error( string $function_name, string $message, int $error_level = E_USER_NOTICE )

Since
6.4.0
Source
wp-includes/functions.php:6194

Emits a debug-only PHP notice, warning, or deprecation message tied to a function name, but only fires the underlying trigger_error() call when WP_DEBUG is truthy. Two actions (wp_trigger_error_always_run, wp_trigger_error_run) and one filter (wp_trigger_error_trigger_error) let code observe or veto the message before it is sanitized with wp_kses() and handed off. Core helpers like _deprecated_function() and _doing_it_wrong() are built on top of it, so knowing its hook order matters if you're centralizing error logging.

Generates a user-level error/warning/notice/deprecation message.

Description

Generates the message when WP_DEBUG is true.

Compatibility

WordPress
since 6.4.0
PHP
7.4–8.6-dev
  • 6.7.7
  • 6.8.8
  • 6.9.7
  • 7.0.4
  • 7.1.0

Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.

Parameters

$function_namestring
The function that triggered the error.
$messagestring
The message explaining the error.
The message can contain allowed HTML 'a' (with href), 'code', 'br', 'em', and 'strong' tags and http or https protocols.
If it contains other HTML tags or protocols, the message should be escaped before passing to this function to avoid being stripped wp_kses().
$error_levelintoptional
The designated error type for this error.
Only works with E_USER family of constants. Default E_USER_NOTICE.Default: E_USER_NOTICE

Code examples

Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.

Capture a custom warning even when WP_DEBUG is off

A pricing helper wants to warn about an out-of-range discount, and you want to see it in the sandbox regardless of the site's WP_DEBUG setting.

add_action(
	'wp_trigger_error_always_run',
	function ( $function_name, $message, $error_level ) {
		printf(
			'always_run hook: %s() reported "%s" (error level %d).<br>',
			esc_html( $function_name ),
			esc_html( $message ),
			$error_level
		);
	},
	10,
	3
);

wp_trigger_error(
	'acme_calculate_discount',
	'The discount percentage must be between 0 and 100.',
	E_USER_WARNING
);

echo 'wp_trigger_error() call finished.';

The wp_trigger_error_always_run action fires no matter what WP_DEBUG or the trigger_error filter say, which is why this prints on a fresh install.

Suppress a specific deprecation notice with the trigger_error filter

A plugin wants to silence errors coming from one legacy function while still logging that it was called.

add_action(
	'wp_trigger_error_always_run',
	function ( $function_name ) {
		printf( 'always_run fired for %s().<br>', esc_html( $function_name ) );
	},
	10,
	1
);

add_filter(
	'wp_trigger_error_trigger_error',
	function ( $trigger, $function_name ) {
		if ( 'legacy_price_formatter' === $function_name ) {
			return false;
		}
		return $trigger;
	},
	10,
	2
);

add_action(
	'wp_trigger_error_run',
	function ( $function_name ) {
		printf( 'wp_trigger_error_run fired for %s().<br>', esc_html( $function_name ) );
	},
	10,
	1
);

wp_trigger_error(
	'legacy_price_formatter',
	'This formatter is deprecated, use wc_price() instead.',
	E_USER_DEPRECATED
);

echo 'Notice that wp_trigger_error_run never printed because the filter returned false.';

wp_trigger_error_run also requires WP_DEBUG to be truthy, so on a sandbox with debugging off it would stay silent even without the filter.

Common problems and fixes · 4

Why does calling wp_trigger_error() seem to do nothing?

The function returns early right after the wp_trigger_error_trigger_error filter check if WP_DEBUG is not truthy, so on a production or default-config site the message never reaches wp_kses() or the underlying error, and nothing gets logged.

Why is the HTML in my error message getting stripped out?

Before the message is used, wp_trigger_error() runs it through wp_kses(), allowing only a small allowlist and http/https links.

How do I stop a specific function's error from firing without touching its code?

Hook the wp_trigger_error_trigger_error filter and inspect the $function_name argument; returning false from that filter makes wp_trigger_error() bail before the WP_DEBUG check and before the wp_trigger_error_run action ever fires.

What's the difference between wp_trigger_error_always_run and wp_trigger_error_run?

They fire at different points in the same call and under different conditions, so a callback on one may run while the other never does.

Alternatives and related functions

_deprecated_function
When you need to flag an entire function as deprecated with a version number and an optional replacement, since that helper formats and calls wp_trigger_error() for you.
_doing_it_wrong
When code is being used incorrectly rather than being deprecated, since that helper builds a standard message around the same debug-gated mechanism.
_deprecated_argument
When a specific argument or usage pattern of a function is deprecated rather than the whole function.

Performance profile

How much work a call to wp_trigger_error() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.

Cost class
Trivial

Touches nothing outside its own arguments.

Scaling
Constant

No loop in the body: the same number of instructions runs whatever you pass in.

Instructions
18–44

Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 50.

Plugin surface
3 hooks

Third-party callbacks on 'wp_trigger_error_always_run', 'wp_trigger_error_trigger_error', 'wp_trigger_error_run' run inside this call, and their cost is not bounded by anything here.

Called by
48

48 places in core call this, so the cost is paid more often than your own code shows.

What it touches

  • hookthird-party callbacksdo_action()called directly

What one call costs · 3 distinct outcomes

One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_trigger_error() can have, taken from its control-flow graph on PHP 8.5.

WhenInstructionsCalls it makes
always18–20do_action(), apply_filters()
apply_filters() && $error_level === 25639–43do_action(), apply_filters(), do_action(), wp_kses()
apply_filters() && $error_level !== 25640–44do_action(), apply_filters(), do_action(), wp_kses(), trigger_error()

Across PHP versions

PHPCompiledExecutedBranchesNotes
8.6-dev5018–444
8.55018–444
8.45018–4442 fewer instructions than PHP 8.3
8.35218–464
8.25218–464
8.15218–464
7.45218–464

An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.

Hooks and filters fired · 3

3 hooks fire while wp_trigger_error() runs, in this order:

  1. do_action( wp_trigger_error_always_run )actionline 6206 (+12 into the body)

    Always fires when the given function triggers a user-level error/warning/notice/deprecation message.

  2. apply_filters( wp_trigger_error_trigger_error )filterline 6218 (+24 into the body)

    Filters whether to trigger an error.

  3. do_action( wp_trigger_error_run )actionline 6238 (+44 into the body)

    Fires when the given function triggers a user-level error/warning/notice/deprecation message.

Uses · 4

  • do_action()Calls the callback functions that have been added to an action hook.
  • apply_filters()Calls the callback functions that have been added to a filter hook.
  • wp_kses()Filters text content and strips out disallowed HTML.
  • WP_Exception::__construct()

Used by · 48

Show all 48

Source code

function wp_trigger_error( $function_name, $message, $error_level = E_USER_NOTICE ) {	/**	 * Always fires when the given function triggers a user-level error/warning/notice/deprecation message.	 *	 * Can be used to attach custom error handlers even if WP_DEBUG is not truthy.	 *	 * @since 7.0.0	 *	 * @param string $function_name The function that triggered the error.	 * @param string $message       The message explaining the error.	 * @param int    $error_level   The designated error type for this error.	 */	do_action( 'wp_trigger_error_always_run', $function_name, $message, $error_level ); 	/**	 * Filters whether to trigger an error.	 *	 * @since 7.0.0	 *	 * @param bool   $trigger       Whether to trigger the error. Default true.	 * @param string $function_name The function that triggered the error.	 * @param string $message       The message explaining the error.	 * @param int    $error_level   The designated error type for this error.	 */	if ( ! apply_filters( 'wp_trigger_error_trigger_error', true, $function_name, $message, $error_level ) ) {		return;	} 	// Bail out if WP_DEBUG is not turned on.	if ( ! WP_DEBUG ) {		return;	} 	/**	 * Fires when the given function triggers a user-level error/warning/notice/deprecation message.	 *	 * Can be used for debug backtracking.	 *	 * @since 6.4.0	 *	 * @param string $function_name The function that triggered the error.	 * @param string $message       The message explaining the error.	 * @param int    $error_level   The designated error type for this error.	 */	do_action( 'wp_trigger_error_run', $function_name, $message, $error_level ); 	if ( ! empty( $function_name ) ) {		$message = sprintf( '%s(): %s', $function_name, $message );	} 	$message = wp_kses(		$message,		array(			'a'      => array( 'href' => true ),			'br'     => array(),			'code'   => array(),			'em'     => array(),			'strong' => array(),		),		array( 'http', 'https' )	); 	if ( E_USER_ERROR === $error_level ) {		throw new WP_Exception( $message );	} 	trigger_error( $message, $error_level );}

Changelog

Introduced in 6.4.0. Unchanged from 6.7.7 through 7.1.0.

  1. 6.7.7
  2. 6.8.8
  3. 6.9.7
  4. 7.0.4
  5. 7.1.0

Signature, return type and hooks compared across 5 parsed releases.

About this page

Parsed data
Generated from the wordpress-develop 7.1.0 tag, from src/wp-includes/functions.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.
Corrections
Something wrong on this page? Report it and it gets fixed in the next regeneration.