-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add wp_trigger_error() and tests #5144
Add wp_trigger_error() and tests #5144
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hellofromtonya Implementation looks great to me.
I left a comment in https://core.trac.wordpress.org/ticket/57686#comment:20, I'd love for us to define the scope for when to use the new function a bit better. Potentially the outcome could even be added to the function doc-block as that would convey the message to any 3P developer browsing the docs too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great @hellofromtonya!
Yep, this looks okay, quite similar to the earlier PR: #5122. Was thinking it would probably be better to use the new |
} | ||
|
||
/** | ||
* Fires when the given function triggers a user-level error/warning/notice/deprecation message. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a filter, it's an action :)
Actually wondering which may be more useful here:
- Seems an action can only be used to do
debug_backtrace()
(although there is a warning about using it in PHP 7+). - A filter can also be used for
debug_backtrace()
but can also be used to short-circuit the rest of the function. Could that be useful in some cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A filter can also be used for debug_backtrace() but can also be used to short-circuit the rest of the function. Could that be useful in some cases?
What would be a valid use case to short-circuit trigger_error()
when WP_DEBUG
is on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each of the _deprecated_*()
and _doing_it_wrong()
already have a short-circuit built into them. I'm thinking wp_trigger_error()
doesn't need a short-circuit, as it's just a trigger_error()
wrapper.
@azaozz I agree. Follow-up patches and commits will happen once it's introduced into Core. I noted follow-up actions here https://core.trac.wordpress.org/ticket/57686#comment:24. |
$message = sprintf( '%s(): %s', $function_name, $message ); | ||
} | ||
|
||
trigger_error( $message, $error_level ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would probably be a bit better if it was using esc_html()
(if available) for the message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the existing trigger_error()
instances in Core use esc_html()
including _doing_it_wrong()
and _deprecated_*()
functions. Should they be?
The error messages are intended for the server logs. For those messages, escaping isn't necessary.
What about when errors are posted to the screen?
I think the messages are hardcoded, not pulled from the database or user input. Right? If yes, then escaping shouldn't be necessary either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this more ... trigger_error()
is for hardcoded PHP error/warning/notice/deprecation messages. I don't think they need escaping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing a $message
of '<script>alert( "Howdy!" );</script>'
will output an alert to the browser window. It's theoretically possible that a wp_trigger_error()
call could include a $message
parameter containing user input or the like. Escaping late here might be worth doing.
However it's worth noting that the other functions don't currently do this, but would start to if we implement escaping here and make the planned change from their trigger_error()
calls to wp_trigger_error()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tested.
Update: Silly me - I already added esc_html( $message )
while testing. 🤦♀️
Ignore this comment please.
The output of trigger_error()
is a string
. Thus any HTML is output as a string, rather than a valid HTML element within the browser.
For example:
wp_trigger_error( '', 'Message <strong>should not include</strong> <script>alert( "Howdy!" );</script> the function as this is not within a function scope.' );
outputs in Chrome and Edge as:
<br>
<b>Notice</b>": Message <strong>should not include</strong> <script>alert( "Howdy!" );</script> the function as this is not within a function scope. in " <b>/var/www/src/wp-includes/functions.php</b> on line <b>6080</b><br>
outputs in Firefox as:
<br>
<b>Notice</b>: Message <strong>should not include</strong> <script>alert( "Howdy!" );</script> the function as this is not within a function scope. in <b>/var/www/src/wp-includes/functions.php</b> on line <b>6080</b><br>
As it's a string and not valid HTML, escaping shouldn't be needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Appears it does need to be escaped if the message is to be displayed in the browser.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warning HTML entities in message are not escaped. Use htmlentities() on the message if the error is to be displayed in a browser.
Heh, yes, thinking this is the reason why most (all?) other strings/messages that come from PHP or WP, like in die()
are HTML escaped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applying this new function in each _deprecated_*()
and _doing_it_wrong()
function ensures their messages are also escaped. Cool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done ee89718 ✅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch @azaozz ! With that, I think this PR is ready for commit.
For using it in _doing_it_wrong()
and _deprecated_*()
functions, I think I'll do a follow-up PR as the batch likely needs a proper discussion.
Thank you everyone for your contributions! Committed via https://core.trac.wordpress.org/changeset/56530. |
Introduces
wp_trigger_error()
as a wrapper around PHP's nativetrigger_error()
.As a wrapper, it's lean and not opinionated about the message.
The What
Does not trigger the error if
WP_DEBUG
is nottrue
.Includes
wp_trigger_error_run
action to allow hooking in for backtracing and deeper debug._doing_it_wrong()
includes a similar action.Currently the function name is passed to it, similar to
_doing_it_wrong()
. The function's name is added to the start of the message to tie the function to the message.The function name could be computed from:
But then I wondered:
Are there use cases where the developer does not want the function name put into the message, but rather would like to construct the message themselves?
Or are there use cases where the developer does not want the function name at all in the message?
For both of these cases, the developer can pass an empty string for the
$function_name
parameter.Unlike
_doing_it_wrong()
, this new function is a wrapper to only trigger the error when inWP_DEBUG
mode. Where_doing_it_wrong()
intends to loudly alert developers "Hey you're doing it wrong - fix it",wp_trigger_error()
is not opinionated and does not add wording. Rather, it passes the given message totrigger_error()
.Let the messaging come from the calling code, i.e. at the point in the call stack where the error/warning/notice/deprecation happens. Keep it simple.
References:
trigger_error()
https://www.php.net/manual/en/function.trigger-error.phpTrac ticket: https://core.trac.wordpress.org/ticket/57686
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.