Problem/Motivation

If your module is broken during development you can easily end up with an exception being rendered.
Sadly your code also breaks the rendering of that exception page easily, which results in pointless errors.

Proposed resolution

Decouple exception/error rendering from the rest of rendering,

... https://github.com/filp/whoops is pretty cool as it helps you to debug really deep problems.

Remaining tasks

User interface changes

API changes

CommentFileSizeAuthor
#1 2376153-1.patch8.32 KBdawehner
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

FileSize
8.32 KB
Wim Leers’s picture

That looks very helpful.

dawehner’s picture

Issue summary: View changes
Issue tags: +DX (Developer Experience)
ryan.armstrong’s picture

I can attest that Whoops is VERY helpful at debugging.

dawehner’s picture

@ryan.armstrong
Do you want to try to research how to properly integrate it into core?

ryan.armstrong’s picture

Actually yea I can take a look at that. Now that StackPHP is in core we could use the middleware.

Aki Tendo’s picture

I finally took the time to give this a close look over and I would like to fold this into the Well Formed Errors Initiative. This is too large a change to fold into Drupal 8.0 - the error code is too disparate and needs to be consolidated. I am currently developing an assertion handler to staunch the bleeding of the worst of the super cryptic error and start the practice of adding assert statements into the code.

Whoops would give us a foundation for a unified message output format when in verbose mode. The code I was planning to write has the goal of codifying the error messages themselves and transferring their contents out into YAML files, like this one for a twigextension assertion failure:

Core.Template.TwigExtension.getLink.noLinkGenerator: |
  There was no link generator attached to the TwigExtension object. The most likely cause is a module has 
  misconfigured it.
  Example of a correct configuration file:

    services:
      myModule.twig_extension:
        class: Drupal\cta_module\TwigExtension
        tags:
          - { name: twig.extension }
        calls:
          - [setGenerators, ['@url_generator']]
          - [setLinkGenerator, ['@link_generator']]

  This particular assertion will fail if the last line, setLinkGenerator, is missing.

  To correct this error you will need to fix your configuration then rebuild the
  service container using the <a href="https://api.drupal.org/api/drupal/core!rebuild.php/8">rebuild script.</a> 
  Until you do Drupal cannot proceed beyond this assertion failure point.

  <strong>See</strong>
  <a href="https://www.drupal.org/node/1831138">Building Custom Twig Extensions</a>

This information is not at odds with the stackframe information that Whoops provides.

The incorporation of Whoops into the Well Formed Error Initiative does involve writing extended Handler classes that can load the error codes from the yml files. Also an Assertion Handler based on Whoops handle interface will need to be written as well. But it should work out very well.

Thoughts?

dawehner’s picture

@Aki Tendo
Its great what you are working on, but please keep in mind that the only way to achieve something are small steps.

Aki Tendo’s picture

Steps should be no larger or smaller than they need to be. Anyway, I'm getting a bit excited at the possibilities of putting this together. But before a single line of code gets written I need to take the step of drafting the API.

I've finished my first overview of Whoops and I think it will make for a fine error presentation layer. What my current project is about is error composition and error system setup - presentation was in my original plan largely an afterthought because those first two points are kinda massive on their own.

dawehner’s picture

One thing I'd like to see at some point is that in case we render the exception we should not depend on any code in Drupal which could be broken as well.
Using whoops helps with that, because its just whoops, and nothing else.

Crell’s picture

Another similar library worth investigating is BooBoo, from The PHP League: http://booboo.thephpleague.com/

(I've not used either one so have no opinion as to their relative quality, just that both exist and deserve evaluation.)

Aki Tendo’s picture

Both of these solutions share a problem - they do not lazy load. That is, they must load themselves *entirely* into memory. The Fault System I've devised only loads pointers to the error handling system that don't go over until tripped. I will expand it somehow to do a handoff to a third party library, but neither solution is idea for mainline use because of their overhead.

dawehner’s picture

@Aki Tendo
Do you think these libraries could be easily made lazy loadable? We don't have to reinvent the wheel here.

Crell’s picture

How are they not lazy loading? They both use composer for autoloading (so no class has any impact on the system until it's actually used) and their initial setup at least seems fairly cheap. Instantiating an object or two is fairly inexpensive in modern PHP versions. We'd get much more mileage out of eliminating an SQL query than prematurely optimizing here. :-)

Aki Tendo’s picture

The moment you invoke a call from the class to set_error_handler or set_exception_handler the class is loaded. I was reminded of this while developing the Fault system. That's the reason a static method in the FaultSetup method was used instead of instantiating the object directly. Instead the object is loaded and instantiated at the last possible moment. I need to study Whoops and BooBoo more to see if they allow for this.

The main error find tool I want is symfony/var-dumper and it's associated Twig extensions. The first version of this patch used dump but that needed to be removed to for the minimal 8.0.x version.

Crell’s picture

As I said, especially with an opcode cache (which any self-respecting site uses now a days) the performance cost of loading the one file with the class in it is small enough to be negligible. There are WAAAAY bigger fish to fry than that micro-optimization.

Aki Tendo’s picture

Op code caches don't remove the processing of the instructions - just the compiling of the code. As for the value of such optimization - most bloated software has no one big pig piece causing it to crawl, rather the problem is hundreds to thousands of small wasting actions that have accumulated and were put in place due to that attitude.

dawehner’s picture

Fair point, @Aki Tendo but do you think it would be a hard problem to make it actually lazy? Isn't it just about wrapping the existing library and load it, if a error/exception appears?

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

willzyx’s picture

If you are intrested I have create a little sandbox module that integrate Whoops library with Drupal 8 https://www.drupal.org/sandbox/willzyx/2751843

Any help/suggestion is really appreciated :)

Aki Tendo’s picture

I've been away from the code for awhile but I'm ready to dive back in. The ability to allow developers to choose their debugging framework will be a major plus.

My thought is to adjust Drupal not to just use Whoops per se, but any debug framework. Ideally the framework would be loaded by composer, perhaps with a some glue code to make settings the debug suite needs. Also, splitting out the testmode code out of core would be desirable.

I'll turn to this shortly, I have a couple small patches I'd like to get into, I guess 8.3, at this point.

cosmicdreams’s picture

Very interesting... I had no idea that there was a proliferation of these kind of debug frameworks. Can you list a few? I am having trouble finding the kinds of php libraries that you're talking about

Metal3d’s picture

And... any way to fix this ? I have the exact error on 8.1.9 version calling "drush cr"...

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Aki Tendo’s picture

I've been giving this some thought recently. I'm starting to sway into the direction that while enabling optional debug handlers might be desirable this is an instance where leveraging community resources to do this in house makes sense. This is why I feel this way:

First, no outside bug handler - whoops, booboo, or what have you - is going to be written with drupal's code base and community in mind. Why is this important? I feel that it would be very useful to leverage the community in helping people find solutions to the problems at hand.

For example - it's one thing to have an assertion fail and give a nice neatly formatted call stack and variable stats. At the end of the day that's all whoops and booboo can do. A drupal specific package could allow us to encode a discussion page into the error object or error string, and link to that discussion in the error message itself. I also wrote a prototype which scanned the class names on the call stack and, again, linked back to the relevant Drupal API pages. This sort of cross referencing is something no outside project will ever be able to do, and to be honest the more detailed call stack examination can be obtained through xDebug anyway.

On a personal note - I've taken a job where I have a single Drupal 8 website to maintain, so I should be able to devote more time to projects now and on a few projects be able to get permission to work them into my paid work schedule.

dawehner’s picture

This is an interesting thought you do. Having error messages pointing to helpful resources is certaintly a huge plus point.
Symfony fullstack is also providing a specific error message, integrating with other components.

From my point of view whoops is more meant as a one solution fits everything, while booboo is really more designed as a library with flexibility in mind.
Maybe I'm wrong.

On a personal note - I've taken a job where I have a single Drupal 8 website to maintain, so I should be able to devote more time to projects now and on a few projects be able to get permission to work them into my paid work schedule.

That sounds really great. Looking forward to further ideas you have!

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Chi’s picture

The main problem with the current way of rendering error messages is that it encourages developers to write sloppy code. Status messages can always be ignored. It's quite common for Drupal sites to send a few PHP notices/warnings to dblog on each page request.

To avoid this we should display error page with well formatted message for all PHP error levels, even for E_DEPRECATED. I think Symfony takes the same approach.

For BC we could add a new error level debug to system.logging configuration.

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

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

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

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

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

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

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

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should 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.

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

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.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.5.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. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.