Problem/Motivation

When _drupal_log_error() is called with a fatal error, the PHP process exits with a zero:

  if (PHP_SAPI === 'cli') {
    if ($fatal) {
      // When called from CLI, simply output a plain text message.
      // Should not translate the string to avoid errors producing more errors.
      $response->setContent(html_entity_decode(strip_tags(SafeMarkup::format('%type: @message in %function (line %line of %file).', $error))) . "\n");
      $response->send();
      exit;
    }
  }

This causes CLI tools like Behat to exit 0 even though a fatal was raised, confusing CI tools that rely on the exit code.

I'd guess that just exit(1); would be enough here.

Proposed resolution

Remaining tasks

User interface changes

None

API changes

CLI tools that cause a fatal error now exit with an error status, if they use Drupal's default error handler.

Data model changes

None

Release notes snippet

CLI tools that cause a fatal error now exit with an error status, if they use Drupal's default error handler.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

deviantintegral created an issue. See original summary.

arunkumark’s picture

Assigned: Unassigned » arunkumark
arunkumark’s picture

Status: Active » Needs review
FileSize
532 bytes

I have created the patch for returning the true value.

arunkumark’s picture

Assigned: arunkumark » Unassigned
deviantintegral’s picture

Looks fine - any thoughts on how to add test coverage for this?

dawehner’s picture

I fear we would need a test CLI script which calls some code, which causes the fatal.

m4olivei’s picture

+1 to this, I've seen two instances of Behat silently failing as a result of changes in Behat's dependencies.

@dawehner is there precedent for what you propose?

deviantintegral’s picture

Here's a "unit" test that covers this using the Process component. Open to suggestions if log-exit.php should live somewhere else.

Status: Needs review » Needs work

The last submitted patch, 8: 2927012.8-log-error-exit-code.patch, failed testing. View results

deviantintegral’s picture

Status: Needs work » Needs review
FileSize
2.85 KB

I thought that test discovery only tried to inspect files ending in Test, but apparently not. This renames the test script to log-error.sh, which is annoying for editors that try to render as bash but at least matches what core does in core/scripts.

Status: Needs review » Needs work

The last submitted patch, 10: 2927012.10-log-error-exit-code.patch, failed testing. View results

deviantintegral’s picture

Fixing a namespace typo that caused run-tests to fail.

m4olivei’s picture

Status: Needs review » Reviewed & tested by the community

Looks great! Test makes sense, minimal POC script that ultimately calls _drupal_log_error(), then using Symfony Process component to assert the exit status.

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

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now 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.

deviantintegral’s picture

This bug fix would be great to get in 8.5.x and even 8.4.x if another point release is going to be made.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 12: 2927012.12-log-error-exit-code.patch, failed testing. View results

deviantintegral’s picture

Status: Needs work » Reviewed & tested by the community
deviantintegral’s picture

Looks like the prior test failure was unrelated. Tests reran and passed.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/system/tests/src/Unit/Errors/DrupalLogErrorTest.php
    @@ -0,0 +1,25 @@
    +namespace Drupal\Tests\system\Unit\Errors;
    

    This test should be in the core namespace not system since the function under test is core's not system's. Ie. Drupal\Tests\Core\Error

  2. +++ b/core/modules/system/tests/src/Unit/Errors/log-exit.sh
    

    I think we should keep this .php - we have more and more scripts going in as .php which makes everything easy. Also let's put this in core/tests/Drupal/Tests/Core/Error/fixtures

  3. I also think we exit from this script if we're not in running from CLI. Ie.
    if (PHP_SAPI !== 'cli') {
      return;
    }
    
deviantintegral’s picture

Status: Needs work » Needs review
FileSize
2.93 KB

This moves the test and adds the SAPI check.

I can't find any examples of fixtures using the .php suffix - the closest is something like core/tests/Drupal/Tests/Core/Form/fixtures/form_base_test.inc. If the fixture is named log-exit.php this ReflectionException is thrown:

$ core/scripts/run-tests.sh Error
ReflectionException: Class Drupal\Tests\Core\Error\fixtures\log-exit does not exist in /var/www/docroot/core/modules/simpletest/src/TestDiscovery.php:329
Stack trace:
#0 /var/www/docroot/core/modules/simpletest/src/TestDiscovery.php(329): ReflectionClass->__construct('Drupal\\Tests\\Co...')
#1 /var/www/docroot/core/modules/simpletest/src/TestDiscovery.php(177): Drupal\simpletest\TestDiscovery::getTestInfo('Drupal\\Tests\\Co...', '')
#2 /var/www/docroot/core/modules/simpletest/simpletest.module(590): Drupal\simpletest\TestDiscovery->getTestClasses(NULL, Array)
#3 /var/www/docroot/core/scripts/run-tests.sh(1103): simpletest_test_get_all(NULL, Array)
#4 /var/www/docroot/core/scripts/run-tests.sh(145): simpletest_script_get_test_list()
#5 {main}%
alexpott’s picture

Ah that's our magical test discovery assuming everything is a test :)

We have core/tests/fixtures for PHP fixtures that should not be discovered. Imo we should file an issue to improve TestDiscovery to ignore things in fixture directories. But for now we can move this file there and use php.

+++ b/core/tests/Drupal/Tests/Core/Error/fixtures/log-exit.sh
@@ -0,0 +1,48 @@
+ * @see \Drupal\Tests\system\Kernel\Error\DrupalLogErrorTest

Needs updating to the new namespace.

deviantintegral’s picture

Good catch on the namespace comment.

This patch fixes that along with moving the test script. As well, it explicitly tests the PHP output so errors like invalid PHP or a bad path don't give us a false pass.

deviantintegral’s picture

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

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now 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.

deviantintegral’s picture

Straight reroll against 8.7.x.

voleger’s picture

mtift’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
3.15 KB
1.89 KB
2.42 KB

Well can make the test a bit more contained, the script a bit less complex and also less PHP code lying around.

The last submitted patch, 28: 2927012-28.test-only.patch, failed testing. View results

deviantintegral’s picture

TIL'ed about PhpProcess. Nice!

#28 looks fine, but $path is now unused. It's such a minor fix that if tests pass I will bump this to RTBC.

deviantintegral’s picture

Status: Needs review » Reviewed & tested by the community

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.

larowlan’s picture

Can we get a change record for this - even though its a bug, people might have tests that now start (correctly!) failing and it would be good if they went to list-changes if they saw this.

alexpott’s picture

alexpott’s picture

Issue summary: View changes
Issue tags: +8.7.3 release notes

Updated the issue summary. I think we should consider this a bug fix that should go in 8.7.x so I've created the CR with those values and tagged the issue accordingly. However, if others feel we can only do this in 8.8.x, so be it, as getting this fixed is more important than arguing which release it belongs in.

deviantintegral’s picture

Agreed this should go in 8.7.x, especially as this affects fatal errors.

Change record looks good to me.

  • larowlan committed 08879cc on 8.8.x
    Issue #2927012 by deviantintegral, alexpott, arunkumark:...

  • larowlan committed 09bfe7f on 8.7.x
    Issue #2927012 by deviantintegral, alexpott, arunkumark:...
larowlan’s picture

Version: 8.8.x-dev » 8.7.x-dev
Status: Reviewed & tested by the community » Fixed

Committed 08879cc and pushed to 8.8.x. Thanks!

c/p as 09bfe7fa12 to 8.7

Published change record.

Status: Fixed » Closed (fixed)

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