Followup #2999721: [META] Deprecate the legacy include files before Drupal 9

Problem/Motivation

There is already an existing utility Error class. So lets keep things together.
Deprecate legacy errors.inc file functions. Just get rid of errors.inc file in drupal:10.0.x.

Proposed resolution

Convert all error handler related functions to the methods in the Error class.
That will help to work on the next step of modernizing Drupal error handler in #1722694: Fixed Kernel::init() overrides Drupal's error handling configuration without carrying out of legacy errors.inc file loading BC layer in Drupal 10.0.0.

Remaining tasks

  • Deprecate functions
  • Replace usages in the code
  • Add legacy tests

User interface changes

-

API changes

  • new methods in \Drupal\Core\Utility\Error class
  • deprecated error handler related functions

Data model changes

-

Release notes snippet

-

CommentFileSizeAuthor
#113 3000229-113.patch69.8 KBajaypratapsingh
#105 3000229-105.patch68.77 KBvoleger
#102 3000229-102.patch68.77 KBvoleger
#100 interdiff-3000229-97-100.txt10.07 KBvoleger
#100 3000229-100.patch68.23 KBvoleger
#97 3000229-97.patch61.96 KBhimanshu_sindhwani
#95 3000229-95.patch460 byteshimanshu_sindhwani
#94 interdiff-3000229-91-94.txt1.23 KBvoleger
#94 3000229-94.patch64.87 KBvoleger
#91 interdiff-3000229-88-91.txt9.83 KBvoleger
#91 3000229-91.patch64.37 KBvoleger
#88 interdiff-3000229-83-88.txt4.84 KBvoleger
#88 3000229-88.patch63.53 KBvoleger
#83 interdiff-3000229-81-83.txt832 bytesmartin107
#83 3000229-83.patch62.91 KBmartin107
#81 interdiff-3000229-78-81.txt1.28 KBmartin107
#81 3000229-81.patch62.89 KBmartin107
#78 3000229-78.patch62.88 KBmartin107
#78 interdiff-3000229-76-78.txt2.08 KBmartin107
#76 3000229-76.patch63.09 KBmartin107
#72 3000229-72.patch63.17 KBvoleger
#69 3000229-69-9.0.x.patch54.63 KBvoleger
#68 3000229-68.patch62.74 KBandypost
#68 interdiff.txt1.13 KBandypost
#60 3000229-60.patch62.75 KBandypost
#56 3000229-56.patch62.75 KBvoleger
#56 3000229-56-DO-NOT-COMMIT-INCLUDES-3052703-5.patch81.37 KBvoleger
#53 interdiff-3000229-51-53.txt1.12 KBvoleger
#53 3000229-53.patch63.03 KBvoleger
#51 interdiff-3000229-46-51.txt12.83 KBvoleger
#51 3000229-51-without-silence.patch62.62 KBvoleger
#51 3000229-51.patch62.62 KBvoleger
#51 3000229-51-JUST-REROLL.patch62.43 KBvoleger
#46 interdiff-3000229-43-46.txt1.09 KBvoleger
#46 3000229-46.patch62.43 KBvoleger
#43 interdiff-3000229-41-43.txt564 bytesvoleger
#43 3000229-43.patch62.62 KBvoleger
#41 interdiff-3000229-39-41.txt1.53 KBvoleger
#41 3000229-41.patch62.2 KBvoleger
#39 interdiff-3000229-38-39.txt12.64 KBvoleger
#39 3000229-39.patch60.75 KBvoleger
#38 interdiff-3000229-36-38.txt3.91 KBvoleger
#38 3000229-38.patch60.36 KBvoleger
#36 3000229-36.patch60.25 KBmartin107
#33 interdiff-3000229-29-33.txt19.69 KBvoleger
#33 interdiff-3000229-31-33.txt15.93 KBvoleger
#33 3000229-33.patch60.82 KBvoleger
#31 interdiff-3000229-29-31.txt35.49 KBvoleger
#31 3000229-31.patch77.24 KBvoleger
#29 interdiff-3000229-23-29.txt15.33 KBvoleger
#29 3000229-29.patch44.4 KBvoleger
#23 interdiff-3000229-20-23.txt8.57 KBvoleger
#23 3000229-23.patch44.29 KBvoleger
#20 interdiff-3000229-18-20.txt9.28 KBvoleger
#20 3000229-20.patch40.83 KBvoleger
#18 3000229-16-18.txt1.58 KBvoleger
#18 3000229-18.patch40.65 KBvoleger
#16 3000229-13-16.txt6.5 KBvoleger
#16 3000229-16.patch40.64 KBvoleger
#13 interdiff-3000229-11-13.txt1.29 KBvoleger
#13 3000229-13.patch36.94 KBvoleger
#11 3000229-11.patch36.8 KBvoleger
#6 interdiff-3000229-04-05.txt3.94 KBvoleger
#5 3000229-05.patch35.83 KBvoleger
#4 interdiff-3000229-02-04.txt2.55 KBvoleger
#4 3000229-04.patch34.13 KBvoleger
#2 3000229-02.patch32.96 KBvoleger

Issue fork drupal-3000229

Command icon 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

voleger created an issue. See original summary.

voleger’s picture

Status: Active » Needs work
StatusFileSize
new32.96 KB

To do:

  • Add CR;
  • Add @trigger_error calls for deprecated functions;
voleger’s picture

voleger’s picture

StatusFileSize
new34.13 KB
new2.55 KB

Added @trigger_error messages.

voleger’s picture

Status: Needs work » Needs review
StatusFileSize
new35.83 KB

Added deprecation messages.
Patch looks ready for review.

voleger’s picture

StatusFileSize
new3.94 KB
voleger’s picture

Title: [META] Deprecate contents of errors.inc » Deprecate contents of errors.inc

This is not a meta issue now

The last submitted patch, 4: 3000229-04.patch, failed testing. View results

voleger’s picture

As it touches error handling processes add Needs framework manager review tag to the issue.

catch’s picture

Title: Deprecate contents of errors.inc » Convert the error handler to a class

Giving this a more specific title.

voleger’s picture

Issue summary: View changes
StatusFileSize
new36.8 KB

Rerolled after #2947291: Missing argument 5 for _drupal_error_handler()
Marked converted methods from _drupal_*functions as internal.

goodboy’s picture

  1.    public static function handler($error_level, $message, $filename = NULL, $line = NULL, $context = NULL) {
         if ($error_level & error_reporting()) {
           $types = static::levels();
    -      list($severity_msg, $severity_level) = $types[$error_level];
    +      if (isset($types[$error_level]) {
    +        list($severity_msg, $severity_level) = $types[$error_level];
    +      }
    +      else {
    +        // Default values.
    +        $severity_msg = 'Unknown error';
    +        $severity_level = RfcLogLevel::ERROR;
    +      } 
           $backtrace = debug_backtrace();
           $caller = static::getLastCaller($backtrace);
     
           // We treat recoverable errors as fatal.
           $recoverable = $error_level == E_RECOVERABLE_ERROR;
           // As __toString() methods must not throw exceptions (recoverable errors)
           // in PHP, we allow them to trigger a fatal error by emitting a user error
           // using trigger_error().
           $to_string = $error_level == E_USER_ERROR && substr($caller['function'], -strlen('__toString()')) == '__toString()';
           static::log([
    -        '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
    +        '%type' => $severity_msg,
             // The standard PHP error handler considers that the error messages
             // are HTML. We mimick this behavior here.
             '@message' => Markup::create(Xss::filterAdmin($message)),
             '%function' => $caller['function'],
             '%file' => $caller['file'],
             '%line' => $caller['line'],
             'severity_level' => $severity_level,
             'backtrace' => $backtrace,
             '@backtrace_string' => (new \Exception())->getTraceAsString(),
           ], $recoverable || $to_string);
    

    Set default values to $severity_msg and $severity_level at begin of the function.

  2. -      $error_level = isset($GLOBALS['config']['system.logging']['error_level']) ? $GLOBALS['config']['system.logging']['error_level'] : ERROR_REPORTING_HIDE;
    +      $error_level = $GLOBALS['config']['system.logging']['error_level'] ?? ERROR_REPORTING_HIDE;
    

    More compact (https://wiki.php.net/rfc/isset_ternary)

voleger’s picture

StatusFileSize
new36.94 KB
new1.29 KB

#12.1 Thanks, updated
#12.2 It is not BC. See https://3v4l.org/MqbAq . isset_ternary (??) available > php7.0. But Drupal 8 supports > php5.5.9. So I can't change that.

borisson_’s picture

I think this looks great, but I can't do the required framework manager review.

andypost’s picture

Status: Needs review » Needs work

Looks good, some minor feedback
It also needs deprecation test

  1. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -186,4 +189,367 @@ public static function formatBacktrace(array $backtrace) {
    +  public static function levels() {
    +    $types = [
    +      E_ERROR => ['Error', RfcLogLevel::ERROR],
    ...
    +    return $types;
    

    no reason in intermediate variable - just return array

  2. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -186,4 +189,367 @@ public static function formatBacktrace(array $backtrace) {
    +    elseif (DRUPAL_TEST_IN_CHILD_SITE && $error_level === E_USER_DEPRECATED) {
    ...
    +    if (DRUPAL_TEST_IN_CHILD_SITE && !headers_sent() && (!defined('SIMPLETEST_COLLECT_ERRORS') || SIMPLETEST_COLLECT_ERRORS)) {
    

    I'd better add `defined('DRUPAL_TEST_IN_CHILD_SITE')` to condition

  3. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -186,4 +189,367 @@ public static function formatBacktrace(array $backtrace) {
    +  public static function log(array $error, $fatal = FALSE) {
    +    $is_installer = drupal_installation_attempted();
    

    that makes me think about this function still should be loaded to make this class selfcontained, also a lot of services accesses via \Drupal::

  4. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -186,4 +189,367 @@ public static function formatBacktrace(array $backtrace) {
    +      $error_level = isset($GLOBALS['config']['system.logging']['error_level']) ? $GLOBALS['config']['system.logging']['error_level'] : ERROR_REPORTING_HIDE;
    

    Use ?: instead of isset()

voleger’s picture

Status: Needs work » Needs review
StatusFileSize
new40.64 KB
new6.5 KB

#15.1 - fixed
#15.2 - fixed
#15.3 - included bootstrap.inc file
#15.4 - this will trigger notice level error. kept as it is.
Added tests.

Status: Needs review » Needs work

The last submitted patch, 16: 3000229-16.patch, failed testing. View results

voleger’s picture

Status: Needs work » Needs review
StatusFileSize
new40.65 KB
new1.58 KB

Replaced DRUPAL_ROOT by the service call

Status: Needs review » Needs work

The last submitted patch, 18: 3000229-18.patch, failed testing. View results

voleger’s picture

Status: Needs work » Needs review
StatusFileSize
new40.83 KB
new9.28 KB

Fixed failing tests, reverted replacements of DRUPAL_ROOT.

voleger’s picture

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

voleger’s picture

StatusFileSize
new44.29 KB
new8.57 KB

added _drupal_exception_handler and _drupal_exception_handler_additional

voleger’s picture

Issue tags: -Needs framework manager review
voleger’s picture

Issue summary: View changes
voleger’s picture

voleger’s picture

Issue summary: View changes
dawehner’s picture

+++ b/core/tests/Drupal/Tests/Core/Utility/LegacyErrorTest.php
@@ -0,0 +1,104 @@
+class LegacyErrorTest extends UnitTestCase {
...
+   */
+  protected function setUp() {
+    parent::setUp();
+    include_once $this->root . '/core/includes/bootstrap.inc';
+    include_once $this->root . '/core/includes/errors.inc';
+  }

I don't think unit tests should load include files, would it be able to make this a kernel test

voleger’s picture

StatusFileSize
new44.4 KB
new15.33 KB

Addressed #28
Also updated deprecation messagess regarding new CS rules.

aaronmchale’s picture

Any chance we could do this instead? #1722694: Fixed Kernel::init() overrides Drupal's error handling configuration

Also see my comment on the issue about how to make Symfony's Error Handling work with our level of granularity: #23

I think there would be significant benefits to doing this, one that comes to mind is a much nicer debugging experience, really I cannot stress enough how nice it is compared to Drupal's.

voleger’s picture

StatusFileSize
new77.24 KB
new35.49 KB

Here added shutdown handler and deprecated ERROR_REPORTNIG_* constants.

berdir’s picture

+++ b/core/includes/bootstrap.inc
@@ -1015,56 +1035,29 @@
  */
 function &drupal_register_shutdown_function($callback = NULL) {
-  // We cannot use drupal_static() here because the static cache is reset during
-  // batch processing, which breaks batch handling.
-  static $callbacks = [];
-

I'm not sure about moving this to the Error class.

It's not specific to errors, it's shutdown stuff that should happen always (including errors) so I feel like that should be its own thing, what is the reason for moving it to Error?

voleger’s picture

Parent issue: » #2999721: [META] Deprecate the legacy include files before Drupal 9
Related issues: +#3053773: Move shutdown functions into the shutdown handler class.
StatusFileSize
new60.82 KB
new15.93 KB
new19.69 KB

I created followup for the shutdown handler - #3053773: Move shutdown functions into the shutdown handler class.
Reverted changes related to shutdown functions.
So here two interdiffs:
31-33 - revert shutdown functions changes
29-33 - ERROR_REPORTING_* constants deprecations

voleger’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Needs reroll

martin107’s picture

Assigned: Unassigned » martin107

I am rerolling

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new60.25 KB

Not the easiest of rerolls

function from error.inc copied and mutated slight as they move into Error.php

Here are the code changes as I see them. Lets hope I have dealt with everything cleanly.

A)

   if (DRUPAL_TEST_IN_CHILD_SITE && !headers_sent() && (!defined('SIMPLETEST_COLLECT_ERRORS') || SIMPLETEST_COLLECT_ERRORS)) {
> +      static::header($error['@message'], $error['%type'], $error['%function'], $error['%file'], $error['%line']);    }
821,822c812

The logic for this conditional has been updated in core recently.

B)

The try catch pattern in Error:exceptionHandler() has been simplified

   try {
      // Log the message to the watchdog and return an error page to the user.
      static::log(static::decodeException($exception), TRUE);
    }
    // Catch \Throwable, which covers both Error and Exception throwables.
    catch (\Throwable $error) {
      static::exceptionHandlerAdditional($exception, $error);
    }

Status: Needs review » Needs work

The last submitted patch, 36: 3000229-36.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

voleger’s picture

Status: Needs work » Needs review
StatusFileSize
new60.36 KB
new3.91 KB

A) This update from Drupal causes the bug during LegacyTest API calls. So here the fix.
B) Happy to see dropped support of php5

voleger’s picture

StatusFileSize
new60.75 KB
new12.64 KB

And complete fixes related to CS issues of deprecation messages.

martin107’s picture

Assigned: martin107 » Unassigned
Issue tags: -Needs reroll

thank you -- I had half finished my corrections but Mondays are always a little busy.

In term of review this looks good to me. - The Legacy test did need adjustment.

voleger’s picture

StatusFileSize
new62.2 KB
new1.53 KB

Found 1 missed replacement (wondering why the test not failed previously)
Added errors.inc file deprecation message.
Still needs review

Status: Needs review » Needs work

The last submitted patch, 41: 3000229-41.patch, failed testing. View results

voleger’s picture

StatusFileSize
new62.62 KB
new564 bytes

missed include call

voleger’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 43: 3000229-43.patch, failed testing. View results

voleger’s picture

Status: Needs work » Needs review
StatusFileSize
new62.43 KB
new1.09 KB

Removed file @trigger_error call and added TODO for errors.inc include file remove

Status: Needs review » Needs work

The last submitted patch, 46: 3000229-46.patch, failed testing. View results

voleger’s picture

Status: Needs work » Needs review

Database fail. back to needs review

voleger’s picture

berdir’s picture

  1. +++ b/core/includes/errors.inc
    @@ -3,14 +3,15 @@
      * Functions for error handling.
    + *
    + * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
    + *   See each function in the file for individual deprecation notices with
    + *   upgrade instructions.
    + *
    

    I think so far we didn't explicitly deprecate a file as a while, this is slightly different as it is loaded conditionally but I still think that's covered with deprecating all the functions in it, and when updating that, if someone calls it directly, they can remove that then.

  2. +++ b/core/includes/errors.inc
    @@ -19,27 +20,16 @@
    +  return Error::levels();
    

    I think getLevels() would make more sense here, that also matches \Drupal\Core\Logger\RfcLogLevel::getLevels

  3. +++ b/core/includes/errors.inc
    @@ -293,32 +119,16 @@ function _drupal_log_error($error, $fatal = FALSE) {
    +  @trigger_error('_drupal_get_error_level() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Utility\Error::getLevel() instead. See https://www.drupal.org/node/3009162', E_USER_DEPRECATED);
    +  return Error::getLevel();
    

    Error::getLevel() doesn't seem every explicit in what it returns, what about getCurrentLevel(), that's also better separated from levels/getLevels then.

  4. +++ b/core/includes/errors.inc
    @@ -334,25 +144,14 @@ function _drupal_get_error_level() {
    +  @trigger_error('_drupal_error_header() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Utility\Error::header() instead. See https://www.drupal.org/node/3009162', E_USER_DEPRECATED);
    +  Error::header($message, $type, $function, $file, $line);
    

    same here, I think methods should generally be verbNoun() or just verb(), header isn't a verb :)

    could be addHeader() or something more verbose, some arguments use emit, so could be emitHeader()? but add is probably easier to found. Also not 100% sure about it being public. Most functions are prefixed with _, but so is _drupal_error_handler_real() and that does need to be called. Still, this function is currently only called from within the other error functions and could be a candidate to make protected?

    We had a similar case in file_unmanaged_prepare(), initial patches hat it as public with a @todo to make it internal, but in the end, we just made it protected and kept the old function in place, easier to clean-up/remove then, it's not that much code after all.

    And in combination with it being a protected helper, I kinda like emitHeader() or emitAssertionHeader()

  5. +++ b/core/lib/Drupal/Core/DrupalKernel.php
    @@ -563,6 +564,7 @@ public function loadLegacyIncludes() {
         require_once $this->root . '/core/includes/form.inc';
    +    // ToDo: Remove include of errors.inc from drupal:9.0.x.
         require_once $this->root . '/core/includes/errors.inc';
    

    like above, not sure that's necessary, other functions like database.inc and entity.inc didn't get that todo either. If we keep it, then it should be @todo :)

  6. +++ b/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php
    @@ -154,21 +154,21 @@ public static function getSubscribedEvents() {
     
       /**
        * Wrapper for error_displayable().
        *
        * @param $error
    -   *   Optional error to examine for ERROR_REPORTING_DISPLAY_SOME.
    +   *   Optional error to examine for Error::REPORTING_DISPLAY_SOME.
        *
        * @return bool
        *
    -   * @see \error_displayable
    +   * @see \Drupal\Core\Utility\Error::isDisplayable()
        */
       protected function isErrorDisplayable($error) {
    -    return error_displayable($error);
    +    return Error::isDisplayable($error);
       }
     
    

    do we still need to wrap it now that it is a static method and not a function? Sometimes unit tests use such wrappers to mock different return values,

    Either we could deprecate this method too or we should update the docblock.

  7. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -186,4 +209,411 @@ public static function formatBacktrace(array $backtrace) {
    +  public static function handler($error_level, $message, $filename = NULL, $line = NULL, $context = NULL) {
    +    if ($error_level & error_reporting()) {
    +      $types = static::levels();
    +      if (isset($types[$error_level])) {
    

    are these arguments optional for some kind of PHP BC? Maybe we can simplify it by making them required? $context is also deprecated in PHP 7.2, we could could possibly not define that at all, since we aren't using it anyway.

  8. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -186,4 +209,411 @@ public static function formatBacktrace(array $backtrace) {
    +   */
    +  public static function getLevel() {
    +    // @todo: remove following include during drupal_installation_attempted
    +    // function deprecation.
    +    include_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
    +    // Raise the error level to maximum for the installer, so users are able to
    

    the include is necessary? log() uses it too and I guess we implicitly rely on this being called first?

  9. +++ b/core/tests/Drupal/KernelTests/Core/Utility/LegacyErrorTest.php
    @@ -0,0 +1,97 @@
    +  public function testDrupalErrorHeader() {
    +    // Ignore warnings as function tries to set headers.
    +    $this->assertNull(@_drupal_error_header('Test',
    

    that's pretty ugly :) (the ignore warnings part)

voleger’s picture

StatusFileSize
new62.43 KB
new62.62 KB
new62.62 KB
new12.83 KB

Addressed #50

#50.1 - let's remove the message
#50.2 - updated
#50.3 - updated
#50.4 - updated
#50.5 - just removed todo message. anyway there would be deprecated functions removal process, so calls to the empty script files also wuld be removed during that process.
#50.6 - replaced usages with direct call of Error::isDisplayable()
#50.7 - totaly agree as this is PHP BC. updated
#50.8 - removed
#50.9 - introduced 2 different patches with and without silencing. Lets see wich will not break the legacy test.

Status: Needs review » Needs work

The last submitted patch, 51: 3000229-51-without-silence.patch, failed testing. View results

voleger’s picture

Status: Needs work » Needs review
Related issues: +#3052703: Deprecate drupal_installation_attempted()
StatusFileSize
new63.03 KB
new1.12 KB

#50.8 - the tests from #51 comment shows that lines are necessary. Added reference to #3052703: Deprecate drupal_installation_attempted().
#50.9 - removal of '@' looks good.

Status: Needs review » Needs work

The last submitted patch, 53: 3000229-53.patch, failed testing. View results

voleger’s picture

Status: Needs work » Postponed
voleger’s picture

Prepared two patches:

  • 3000229-56-DO-NOT-COMMIT-INCLUDES-3052703-5.patch - specially to test both patches applied on the current codebase. If it passes - the following patch has to be ready after #3052703: Deprecate drupal_installation_attempted() goes in.
  • 3000229-56.patch - patch rerolled over core codebase that applied changes from #3052703, so it ready for test after unpostponing this issue.
voleger’s picture

Status: Postponed » Needs review

#3052703: Deprecate drupal_installation_attempted() landed
Let's run tests for 3000229-56.patch

voleger’s picture

Tests passed with 3000229-56.patch. See #56. It's ready for review.

andypost’s picture

Status: Needs review » Reviewed & tested by the community

It looks ready to go

  1. +++ b/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php
    @@ -154,21 +154,26 @@ public static function getSubscribedEvents() {
       protected function isErrorDisplayable($error) {
    -    return error_displayable($error);
    +    @trigger_error(__NAMESPACE__ . '::isErrorDisplayable() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Utility\Error::isDisplayable() instead. See https://www.drupal.org/node/3009162', E_USER_DEPRECATED);
    +    return Error::isDisplayable($error);
    

    this method is protected so it needs follow-up to remove
    IIRC we do not remove wrappers on conversion

  2. +++ b/core/lib/Drupal/Core/Session/SessionHandler.php
    @@ -85,10 +85,9 @@ public function write($sid, $value) {
    -      require_once DRUPAL_ROOT . '/core/includes/errors.inc';
    
    +++ b/core/tests/Drupal/Tests/Core/Error/DrupalLogErrorTest.php
    @@ -24,7 +24,6 @@ public function testFatalExitCode() {
    -require_once 'core/includes/errors.inc';
    

    yay!

  3. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -186,4 +210,405 @@ public static function formatBacktrace(array $backtrace) {
    +  public static function getLevels() {
    

    this is not set @internal (as others) and it looks right

andypost’s picture

StatusFileSize
new62.75 KB

Re-roll #56 cos applies with offset

andypost’s picture

voleger’s picture

#60 looks good for me +1 for rtbc

larowlan’s picture

+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -1037,8 +1038,8 @@ public static function bootEnvironment($app_root = NULL) {
-    set_error_handler('_drupal_error_handler');
-    set_exception_handler('_drupal_exception_handler');
+    set_error_handler([Error::class, 'handler']);
+    set_exception_handler([Error::class, 'exceptionHandler']);

so my question here is are we going far enough.

We're replacing one procedural function with a static, and not gaining things like dependency injection, e.g. the ::log method uses the container singleton

is this a first-step towards a proper error handler ala \Symfony\Component\HttpKernel\EventListener\DebugHandlersListener ?

Do we have a larger plan here?

Because if we do, we might find we have to do this again in 9.x.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

voleger’s picture

Yes, definitely #1722694: Fixed Kernel::init() overrides Drupal's error handling configuration is the best candidate for that.
And yes - we will convert Error static class into the proper handler in Drupal 9.
The scope of this issue is to get rid of errors.inc file right now, and use autloadable static methods. That will make easier conversion from static methods to Symfony handler without worry about handling includes file that we actually trying to drop here before Drupal 9.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 60: 3000229-60.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

voleger’s picture

Status: Needs work » Reviewed & tested by the community

Unrelated test fail. Back to RTBC

andypost’s picture

Version: 8.9.x-dev » 9.0.x-dev
Status: Reviewed & tested by the community » Needs review
StatusFileSize
new1.13 KB
new62.74 KB

Fix CS and needs review for 9.0

voleger’s picture

StatusFileSize
new54.63 KB

Here the drupal:9.0.x patch

voleger’s picture

Issue summary: View changes

Added info for the following steps.

voleger’s picture

So we have the patches for drupal:8.8.x and drupal:8.9.x in #68
and a patch in #69 for drupal:9.0.x

voleger’s picture

Version: 9.0.x-dev » 9.1.x-dev
StatusFileSize
new63.17 KB

Rerolled #68 patch against latest 9.0.x

daffie’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

The patch needs a reroll. I did a very quick review:

+++ b/core/lib/Drupal/Core/Utility/Error.php
@@ -185,4 +220,410 @@ public static function formatBacktrace(array $backtrace) {
+   * @param string|null $filename
...
+   * @param int|null $line
...
+  public static function handler($error_level, $message, $filename, $line) {

Are the parameters $filename and $line optional or not?

martin107’s picture

Assigned: Unassigned » martin107

I will do the reroll

martin107’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new63.09 KB

reroll now .. I will work on 74 next

Status: Needs review » Needs work

The last submitted patch, 76: 3000229-76.patch, failed testing. View results

martin107’s picture

Assigned: martin107 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2.08 KB
new62.88 KB

A) Fixed bug... not sure If I have everything.

B) $filename, $line, $context those parameters are no longer needed/used.. so deleted.

Status: Needs review » Needs work

The last submitted patch, 78: 3000229-78.patch, failed testing. View results

martin107’s picture

Assigned: Unassigned » martin107

opps

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new62.89 KB
new1.28 KB

better

Status: Needs review » Needs work

The last submitted patch, 81: 3000229-81.patch, failed testing. View results

martin107’s picture

StatusFileSize
new62.91 KB
new832 bytes

a simple fix.

voleger’s picture

Looks better now.
But what about CS issues?
Can we address them in the followup or in this issue?

martin107’s picture

Assigned: martin107 » Unassigned

I am not sure that I follow

But what about CS issues?

Do you mean coding standard issues ... The test results do not show any additional CS issues.

I think this issue is complete... well ready for review.

daffie’s picture

Patch looks good. Some remarks:

  1. +++ b/core/includes/bootstrap.inc
    @@ -310,18 +337,16 @@ function _drupal_error_handler($error_level, $message, $filename = NULL, $line =
    + * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0.
    + *    Use \Drupal\Core\Utility\Error::exceptionHandler() instead.
    + *
    + * @see https://www.drupal.org/node/3009162
    + * @see \Drupal\Core\Utility\Error::exceptionHandler()
      */
     function _drupal_exception_handler($exception) {
    

    This function is being deprecated. There is however no deprecation message test.

  2. +++ b/core/includes/bootstrap.inc
    @@ -331,16 +356,16 @@ function _drupal_exception_handler($exception) {
     function _drupal_exception_handler_additional($exception, $exception2) {
    

    The same as with _drupal_exception_handler.

  3. +++ b/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php
    @@ -154,21 +154,26 @@ public static function getSubscribedEvents() {
    +   * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0.
    +   *   Use \Drupal\Core\Utility\Error::isDisplayable() instead.
    +   *
    +   * @see https://www.drupal.org/node/3009162
    +   * @see \Drupal\Core\Utility\Error::isDisplayable()
        */
       protected function isErrorDisplayable($error) {
    

    Same as with _drupal_exception_handler.

  4. +++ b/core/includes/errors.inc
    @@ -51,58 +34,22 @@ function drupal_error_levels() {
    +function _drupal_error_handler_real($error_level, $message, $filename = NULL, $line = NULL, $context = NULL) {
    
    +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -185,4 +220,405 @@ public static function formatBacktrace(array $backtrace) {
    +        list($severity_msg, $severity_level) = $types[$error_level];
    

    This can we rewritten to: [$severity_msg, $severity_level] = $types[$error_level];

  5. +++ b/core/includes/errors.inc
    @@ -51,58 +34,22 @@ function drupal_error_levels() {
    -  elseif (DRUPAL_TEST_IN_CHILD_SITE && $error_level === E_USER_DEPRECATED) {
    
    +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -185,4 +220,405 @@ public static function formatBacktrace(array $backtrace) {
    +    elseif (defined('DRUPAL_TEST_IN_CHILD_SITE') && $error_level === E_USER_DEPRECATED) {
    

    This change is not correct. Now we are only testing if the constant exists. We should also be testing that the value is TRUE.

  6. +++ b/core/includes/errors.inc
    @@ -145,147 +89,16 @@ function error_displayable($error = NULL) {
    -  if (DRUPAL_TEST_IN_CHILD_SITE && !headers_sent() && (!defined('SIMPLETEST_COLLECT_ERRORS') || SIMPLETEST_COLLECT_ERRORS)) {
    
    +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -185,4 +220,405 @@ public static function formatBacktrace(array $backtrace) {
    +    if (defined('DRUPAL_TEST_IN_CHILD_SITE') && !headers_sent() && (!defined('SIMPLETEST_COLLECT_ERRORS') || SIMPLETEST_COLLECT_ERRORS)) {
    

    Same as previous point.

  7. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -185,4 +220,405 @@ public static function formatBacktrace(array $backtrace) {
    +    // When running inside the testing framework, we relay the errors
    +    // to the tested site by the way of HTTP headers.
    +    if (defined('DRUPAL_TEST_IN_CHILD_SITE') && !headers_sent() && (!defined('SIMPLETEST_COLLECT_ERRORS') || SIMPLETEST_COLLECT_ERRORS)) {
    +      static::emitAssertionHeader($error['@message'], $error['%type'], $error['%function'], $error['%file'], $error['%line']);
    +
    +    }
    

    Can we remove this empty line.

  8. In the docblock of the function error_displayable() there are 3 mentions of ERROR_REPORTING_DISPLAY_*. Can we replace them.
martin107’s picture

Assigned: Unassigned » martin107

@daffie thanks for the detailed review.

I am on it.

voleger’s picture

Assigned: martin107 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new63.53 KB
new4.84 KB

#86.1, #86.2 and #86.3: first point is that they are internal functions, so they haven't to be used by the contribs or custom module. Also that's why we marked them as @internal in new API. Second point is if we will trigger error in the error handler we will go into recursion. If I understand correctly the error handlers are not so easy to test.
#86.4, #86.5, #86.6,
#86.7 and #86.8 are addressed

voleger’s picture

Title: Convert the error handler to a class » Move error handlers to an Error class
Issue summary: View changes
longwave’s picture

  1. +++ b/core/includes/bootstrap.inc
    @@ -295,8 +315,15 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
    +  @trigger_error('_drupal_error_handler() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Utility\Error::handler() instead. See https://www.drupal.org/node/3009162', E_USER_DEPRECATED);
       require_once __DIR__ . '/errors.inc';
       _drupal_error_handler_real($error_level, $message, $filename, $line, $context);
    

    Why does this still call _drupal_error_handler_real()? Can't it call Error::handler() directly now, like the deprecation message suggests?

  2. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -185,4 +220,407 @@ public static function formatBacktrace(array $backtrace) {
    +  public static function handler($error_level, $message) {
    

    Unsure if this is bikeshedding but we often use verbs as method names so this could just be handle()?

  3. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -185,4 +220,407 @@ public static function formatBacktrace(array $backtrace) {
    +  public static function exceptionHandler($exception) {
    

    Similarly this would read better as handleException()?

  4. +++ b/core/lib/Drupal/Core/Utility/Error.php
    @@ -185,4 +220,407 @@ public static function formatBacktrace(array $backtrace) {
    +  public static function exceptionHandlerAdditional($exception, $exception2) {
    

    And this could be handleAdditionalException()?

  5. +++ b/core/tests/Drupal/Tests/Core/Error/DrupalLogErrorTest.php
    @@ -37,7 +36,7 @@ public function testFatalExitCode() {
    +\Drupal\Core\Utility\Error::log($error, TRUE);
    

    Why not use this class and then only call Error::log() here?

voleger’s picture

StatusFileSize
new64.37 KB
new9.83 KB

Addressed #90

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, looks great now - let's see what framework managers think.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Some thoughts:

  1. core/lib/Drupal/Core/Utility/Error.php needs to be added to the classmap part of core/composer.json - this is because it's not going to be needed on every request. Adding it here will make the autoloader have to do less work.
  2. I think we leave all the function's that are doing \Drupal::service() or the like in this issue and only move the stuff that is truly static. And then we should open a follow-up to the other stuff properly. With this issue it feels like we trading a compromise API (from an OO design perspective) for the same API. I.e. we moved everything around but not much has really changed. We still struggle to unit test our error handling because it is coupled to the globals like \Drupal::root() or whatever.
  3. Have we tested that the @trigger_error in our old error handlers doesn't result in recursive loop? LegacyErrorTest should be setting the old error handlers up and triggering an error to test that they don't break in this situation.
voleger’s picture

StatusFileSize
new64.87 KB
new1.23 KB

Addressed CS issue and #93.1

himanshu_sindhwani’s picture

Status: Needs work » Needs review
StatusFileSize
new460 bytes

Correcting the failing test case in #94.

Status: Needs review » Needs work

The last submitted patch, 95: 3000229-95.patch, failed testing. View results

himanshu_sindhwani’s picture

StatusFileSize
new61.96 KB

Uploaded the wrong patch in #95. Here is a complete fix.

interdiff:

--- a/composer.lock
+++ b/composer.lock
@@ -485,7 +485,7 @@
             "dist": {
                 "type": "path",
                 "url": "core",
-                "reference": "5bd6798a64831fa08a343a14a0ee47127c4cb99f"
+                "reference": "d8a8c903a37bbdc2f7597e0d60c5c7b9b0afcb2e"
             },
             "require": {
                 "asm89/stack-cors": "^1.1",
@@ -707,7 +707,8 @@
                     "lib/Drupal/Core/DrupalKernel.php",
                     "lib/Drupal/Core/DrupalKernelInterface.php",
                     "lib/Drupal/Core/Installer/InstallerRedirectTrait.php",
-                    "lib/Drupal/Core/Site/Settings.php"
+                    "lib/Drupal/Core/Site/Settings.php",
+                    "lib/Drupal/Core/Utility/Error.php"
                 ]
             },
             "scripts": {
himanshu_sindhwani’s picture

Status: Needs work » Needs review
daffie’s picture

Status: Needs review » Needs work

The fix for comment #93.1 is good.

The other 2 points #93.2 and #93.3 are still open.

voleger’s picture

Status: Needs work » Needs review
StatusFileSize
new68.23 KB
new10.07 KB

Added legacy tests for _drupal_exception_handler and _drupal_exception_handler_real
Removed overridden usage of FinalExceptionSubscriber::isErrorDisplayable() in TestDefaultExceptionSubscriber class

longwave’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

All review points were addressed but #100 no longer applies.

voleger’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new68.77 KB

Rerolled

voleger’s picture

If all points addressed can we move it to RTBC?

longwave’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

#102 needs reroll again, but I think this can be set to RTBC after rerolling.

voleger’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new68.77 KB

Here is rerolled patch.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I think we leave all the function's that are doing \Drupal::service() or the like in this issue and only move the stuff that is truly static.

Is not addressed. The Error class is still full of \Drupal calls. With this issue it feels like we trading a compromised API (from an OO design perspective) for the same API. I.e. we moved everything around but not much has really changed. We still struggle to unit test our error handling because it is coupled to the globals like \Drupal::root() or whatever.

I think this issue should start with an API design that is fit for purpose. Doing this issue makes it harder to do this until Drupal 10 because it gives us 2 static APIs to support rather than the single one we have today. This is likely to be hard to do because the error system is very tangly.

I think this patch can deprecate drupal_error_levels() and the constants but the rest of it needs work.

aaronmchale’s picture

Following on from #106 I feel like it would make a lot more sense to focused on #1722694: Fixed Kernel::init() overrides Drupal's error handling configuration instead, as we could just strip out all of the custom error handling that Drupal has and just adapt Symfony's to work for our needs. Thereby reducing overhead and likely solving the issues Alex mentioned in #106.

In comment #1722694-23: Fixed Kernel::init() overrides Drupal's error handling configuration I noted how we could address the issue of Symfony's TRUE/FALSE debugging options to fit our more granular needs:

That might be our only real blocker, and could be addressed by simply initialising the debugger outside of the Symfony Kernel's init function, there's even docs on the Symfony site explaining how to do it, so it's definitely supported.

andypost’s picture

Related issue changed signature

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ajaypratapsingh’s picture

Status: Needs work » Needs review
StatusFileSize
new69.8 KB

Rerolled patch against drupal 9.5.x

voleger’s picture

Version: 9.5.x-dev » 10.1.x-dev

Needs reroll

longwave’s picture

Status: Needs review » Needs work
Issue tags: -Needs reroll

Needs more than just reroll, #106 needs addressing which is a change in direction.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

anybody’s picture

andypost’s picture

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

voleger’s picture

Title: Move error handlers to an Error class » Add DrupalErrorHandler wrapping Symfony ErrorHandler component
Issue tags: +Needs issue summary update