I was trying to solve a testbot problem for somebody, tailing the apache error log on the test suite, and was surprised to find many, many uncaught PHP exceptions in there. I wouldn't think this would be normal or right.

It pollutes the error log, of course, but it seems to me it's a sign of a design problem.

[Thu Oct 04 14:22:11 2012] [error] [client 10.20.0.167] Uncaught PHP Exception Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException: "" at /var/lib/drupaltestbot/sites/default/files/checkout/core/lib/Drupal/Core/EventSubscriber/AccessSubscriber.php line 34

repeated lot of times.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jthorson’s picture

This is a debug_backtrace() from each of the Access_Subscriber line 34 uncaught exceptions. I haven't parsed through it to see if it tells us anything useful (since the format_debug() version certainly didn't).

http://drupaltestbot-dev-mysql.osuosl.test/uncaughtexception.log

EDIT: The above link requires OSUOSL access.

chx’s picture

Title: Many exceptions uncaught during execution of D8 tests » 403 and 404 pages call error_log cluttering server error logs
Priority: Normal » Major

The chain of execution is this: AccessSubscriber.php throws a 403, handleException catches it, dispatches a KernelEvents::EXCEPTION event and causes the ExceptionListener to fire which calls error_log.

Possible solutions include overriding handleException in our kernel not to dispatch the EXCEPTION event. I do not see a point really.

chx’s picture

Component: other » wscci
Assigned: Unassigned » Crell

Handing it over to Crell for guidance.

chx’s picture

And this is major if not critical because it causes our testbot disks to fill up. Ridiculous...

jthorson’s picture

When investigating this, please also consider the NotFoundHttpException chain, which I assume is a similar chain of execution.

Crell’s picture

Not dispatching an EXCEPTION event is a non-starter. But perhaps an alternate ExceptionListener that only calls error_log() for really exceptional exceptions?

chx’s picture

Tell me how to change the even subscribers and I will.

chx’s picture

Assigned: Crell » chx

Crell's short recipe: Subclass ExceptionListener, stick it in the Core\EventSubscriber namespace, and update the code in the DIC registration that registers that listener.

He also approved my battle plan to copy the whole ExceptionListener class and wrap the error_log in an if (!httpexception)

Crell’s picture

Actually, why copy instead of subclass and override?

chx’s picture

Because the whole class is one method :P (almost)

Crell’s picture

Eh, OK, I suppose that's a reason.

chx’s picture

Status: Active » Needs review
FileSize
5.6 KB
1.25 KB

Status: Needs review » Needs work

The last submitted patch, 1803338.patch, failed testing.

chx’s picture

FileSize
5.6 KB
chx’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 1803338.patch, failed testing.

chx’s picture

Status: Needs work » Needs review
FileSize
5.6 KB

The bot is finicky today ;) what's a syntax error or two in the critical patch in the critical path, meh.

Crell’s picture

Ah ha, now I see why this is happening, and why Symfony sites don't melt servers. :-) The assumption is that you'd always have a logger object, so that code path doesn't get called. A Symfony site would. We do not yet. Related: #1289536: Switch Watchdog to a PSR-3 logging framework

Still, we shouldn't hold up on that. Maybe drop a @todo noting why we have to do it so we can back out later. And removing the (c) Fabien Potencier block and such. :-)

katbailey’s picture

If we're going to bother introducing our own class for this - why not leave out the $logger property altogether? Copying the entire class and leaving it exactly as is bar this one little change seems crazy when half of that code will never run.

Crell’s picture

Status: Needs review » Needs work

That makes even more sense. If we add a logger, we can drop this class and go back to the Symfony one, logger and all.

chx’s picture

Status: Needs work » Needs review
FileSize
4.45 KB

Took the axe to it.

Status: Needs review » Needs work

The last submitted patch, 1803338.patch, failed testing.

katbailey’s picture

Status: Needs work » Needs review
FileSize
4.45 KB

I think it makes sense to remove the logger property from the class entirely. And so if we're going that far it seems reasonable to "adopt" the class as our own, i.e. with Drupal coding standards instead of Symfony's.

Crell’s picture

Status: Needs review » Needs work
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php
@@ -0,0 +1,87 @@
+class ExceptionListener implements EventSubscriberInterface
+{

Missed the coding standards for classes and functions. :-)

+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php
@@ -0,0 +1,87 @@
+    // Do not put a line in the server logs for every HTTP error.
+    if (!$exception instanceof HttpExceptionInterface) {

I rechecked, and the Symfony logger is still logging for HTTP 500 errors. I don't know if we want to do that or not. We need to reroll for formatting anyway, so we can add that here if we want, or not.

+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php
@@ -0,0 +1,87 @@
+      // Re-throw the exception as this is a catch-all
+      return;

I know this is in Symfony, but it looks wrong. We're not rethrowing an exception, we're swallowing it. Rightly or wrongly, the comment doesn't match the code. (That said, it is what Symfony is doing, so I'm OK with leaving it as is and opening up an upstream issue to fix the comment at least.)

Otherwise this looks good.

katbailey’s picture

Status: Needs work » Needs review
FileSize
4.44 KB

Missed the coding standards for classes and functions. :-)

Fixed

the Symfony logger is still logging for HTTP 500 errors. I don't know if we want to do that or not.

I think that makes sense, added.

the comment doesn't match the code

Actually both that comment and the one above it were bothering me, so I got rid of the second one seeing as it's incorrect and I don't think we really need a comment there at all, and I changed the previous one to make grammatical sense.

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Yay for fewer gigabyte-sized log files.

jthorson’s picture

Confirmed that this does indeed prevent the uncaught AccessDeniedHttpException from hitting the testbot apache log on at least one of the tests which was causing it earlier.

webchick’s picture

Status: Reviewed & tested by the community » Fixed
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionListener.phpundefined
@@ -0,0 +1,83 @@
+/**
+ * ExceptionListener.

I was going to mark needs work for this, only to discover that this is what passes for PHPDoc in the Symfony project. :\ Egads.

Brainstormed with chx and jthorson on IRC and came up with "Override of Symfony EventListener class to kill 403 and 404 from server logs." Fixed on commit.

Committed and pushed to 8.x. Yay fewer hard drive fill-ups! :)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

tidied up