Problem/Motivation
RFC accepted https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_e_user_e...
Steps to reproduce
core$ git grep E_USER_ERROR
core/includes/errors.inc:34: E_USER_ERROR => ['User error', RfcLogLevel::ERROR],
core/includes/errors.inc:70: $to_string = $error_level == E_USER_ERROR && str_ends_with($caller['function'], '__toString()');
core/lib/Drupal/Component/Diff/DiffFormatter.php:137: trigger_error('Unknown edit type', E_USER_ERROR);
core/lib/Drupal/Component/Utility/ToStringTrait.php:20: trigger_error(get_class($e) . ' thrown while calling __toString on a ' . static::class . ' object in ' . $e->getFile() . ' on line ' . $e->getLine() . ': ' . $e->getMessage(), E_USER_ERROR);
core/lib/Drupal/Component/Utility/ToStringTrait.php:22: // E_USER_ERROR, we terminate execution. However, for test purposes allow
core/modules/big_pipe/src/Render/BigPipe.php:375: trigger_error($e, E_USER_ERROR);
core/modules/big_pipe/src/Render/BigPipe.php:411: trigger_error($e, E_USER_ERROR);
core/modules/big_pipe/src/Render/BigPipe.php:562: trigger_error($e, E_USER_ERROR);
core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php:82: $this->assertEquals(E_USER_ERROR, $this->lastErrorNumber);
Proposed resolution
clean-up usage or make it conditional
- ToStringTrait is deprecated as any exception still will be caught by error hadler
- BigPipe using it instead of properly logging errors
This technique is used to log errors mostly in core because Drupal does not stop execution for user-level errors, allowing the application to log and continue. Maybe it needs changes but it's out of scope of this issue
Remaining tasks
- file MR and change record
- commit
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-3465827
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
berdirToStringTrait might be tricky, because exceptions and __toString() methods don't like each other, unless that has changed somehow?
Comment #3
andypostAnd the suggestion in RFC is to use proper exceptions
Comment #4
andypostComment #5
berdirLooks like exception handling in __toString() methods got fixed in PHP 7.4: https://3v4l.org/5ZJ2i. That means we can drop the try/catch and even consider to deprecate that trait? It's only used in two classes in core.
Comment #7
andypostYes, just 2 implementations to add, and deprecated, now needs to clean-up
_drupal_error_handler_real(), maybe better to split out fixes for the remaining usage for scopeComment #8
andypost@Berdir thank you! it works and the only test needs to be adjusted
Comment #9
andypostThere's just 4 usages in contrib, so needs to improve message and decide with test, polish CR
Comment #10
andypostblocker for PHP 8.4 adoption
Comment #11
andypostProbably deprecation of
ToStringTraitbetter to move to separate issue or it needs second change recordComment #12
andypostAdded to summary why most of time it needs to decide if code needs exception or logging instead of throwing user error as everyone thinks it should be fatal but there's no
exit()or exception re-thrown in handlerComment #13
catchI think for 10.4/11.1 we should change all these to E_USER_WARNING and then open follow-ups for each case to consider adding:
1. an assert() so it fails hard during development
2. An exception from 12.x onwards if that's appropriate
Comment #14
andypostRelated required for BigPipe fix
Comment #17
kim.pepperCreated an MR for #13
Comment #18
andypostSome failures looks fixable
Comment #20
andypostMR!9924 is green now, so it needs follow-up to deprecate
ToStringTraitComment #21
catchI think we should go with https://git.drupalcode.org/project/drupal/-/merge_requests/9924 and then open a follow-up to decide what to do with those individual cases, possibly based off the other MR.
Could the other MR be closed here and the issue summary updated?
Comment #22
andypostOfficial migration docs said different
Moreover exit() (
die()too) now a userland functionRef https://www.php.net/manual/en/migration84.incompatible.php#migration84.i...
Comment #23
catchThe migration docs might say different but we are often dealing with extreme edge cases where we have a choice between failing hard for end users vs informing site owners, this is why I would go with E_USER_WARNING here then a followup for switching to exceptions or whatever else we want to do.
Comment #24
andypostFiled follow-up #3490454: [META] Replace E_USER_WARNING with exception handling for edge cases in error reporting
Updated summary and CR
Comment #25
andypostThere's green 8.4 pipeline using !9924 as patch
Comment #27
andypostit needs more work for 10.4.x/10.5.x
Comment #28
andypost10.5 failed one unit test https://git.drupalcode.org/issue/drupal-3427903/-/jobs/3523954
Comment #29
andypostPassed as addition https://git.drupalcode.org/project/drupal/-/merge_requests/10379/diffs?c...
Comment #30
andypostboth 10.4/10.5 passed https://git.drupalcode.org/issue/drupal-3427903/-/pipelines/353325
Comment #31
quietone commentedThe issue summary proposed resolution is incorrect in that the changes for -
ToStringTraitandBigPipeare being done in a separate issue, #3490454: [META] Replace E_USER_WARNING with exception handling for edge cases in error reporting. And I see that all the needed followups have been made.I reviewed the MR, and with the scope change it is much more straightforward so setting to RTBC. I applied the patch locally and all instances were changed on 10.5.x and 11.x
I read the change record and it is good to go. The versions numbers will likely need an update but that can be done on commit or I will catch it when I review the change records.
Comment #37
catchCommitted/pushed/cherry-picked to 11.x/11.1.x and 10.5.x/10.4.x, respectively. Let's continue in the follow-ups. Thanks everyone.
Comment #40
andypostFatal errors in 8.5 can have backtrace https://wiki.php.net/rfc/error_backtraces_v2