Project

General

Profile

Actions

Bug #61213

closed

[SYS][displayErrors] = 2 allows code be executed even after Fatal Error

Added by Viktor Livakivskyi over 9 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
-
Target version:
-
Start date:
2014-08-26
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
6.1
PHP Version:
5.5
Tags:
Complexity:
Is Regression:
No
Sprint Focus:

Description

Recently I've found strange behaviour of displayErrors setting in TYPO3.
What I though is, that when it is set to '2', then behaviour of error habdling is same, as with '-1', but no override of disaply_errors PHP settings happens.

But in fact it is different.
First of all, display_errors is overriden with any setting, except '-1' (you can find actual code in Bootstrap->configureExceptionHandling()), while descrition tells opposite.
Next it turns exceptionalErros mask to 0, if devIpMask doesn't match, meaning that no errors are treated as exceptional anymore.

So, the result of such actions can be seen in following example:
Let's say, we have such code:

class MyObjectManager {
  ...
  public function processObject(MyObject $obj) {
    $this->user->addRelation($obj);
    $this->persistanceManager->persistAll();
  }
}

You see, that processObject() method expects object of type MyObject and this will result in PHP Catchable Fatal Error to be fired if e.g. NULL is passed. This really happens and ErrorHandler processes this error by handleError() method.
Inside that method there is a check for $this->exceptionalErrors, which is '0' if devIpMask doesn't match, and this prevents from throwing an Exception. The error only gets logged and... code continues it's execution.

So, in the case above it will lead to 'user' object getting relation to NULL and persisting of this realtion.

Setting displayErrors to -1 prevents this behavior and exception is thrown, which results in breaking code execution.

Now I wonder: is it desired behavior of [SYS][displayErrors] = 2 or is it bug?


Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Task #61235: Improve and simplify the description of TYPO3 error handling options, also cleanup the codeClosedMarkus Klein2014-08-27

Actions
Actions #1

Updated by Markus Klein over 9 years ago

Well, it is desired that the value 2 prevents the errors from showing up in FE.
So if the error message shall not be shown to the user in FE (except from devs via devIPmask), what else should happen?

IMO there's only one solution: Either get your code working, or catch the exceptions on your own and show appropriate error messages.

Actions #2

Updated by Viktor Livakivskyi over 9 years ago

Markus, thank you for the answer.

But the problem is in fact, that even surrounding code with try-catch will not help, because no Exception will be thrown. It will not even be processed by registered ProductionExceptionHandler.

It may not show any errors in FE, but it must interrupt script execution, since it is Fatal Error, you know.

Also description in Install Tool is misleading, as I described above.

Actions #3

Updated by Markus Klein over 9 years ago

Ok, I agree the execution shall be stopped.

You can of course capture the exception. You need to try..catch the call to processObject or any other method that is under your control.
The core's ExceptionHandlers are only trigged as last resort.

Actions #4

Updated by Viktor Livakivskyi over 9 years ago

Unfortunately you can't.

See this example, please. It is very simplified version of ErrorHandler from TYPO3.

<?php
function myErrorHandler($errno, $errstr, $errfile, $errline) {
  if ( E_RECOVERABLE_ERROR===$errno ) {
    echo "handled catchable fatal error\n";
    //throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
  }
  //return false;
  return true;
}
set_error_handler('myErrorHandler');

class ClassA {
  public function method_a (ClassB $b) {
      echo "Inside of method_a()\n";
  }
}

class ClassWrong{}

try{
  $a = new ClassA;
  $a->method_a(new ClassWrong);
}
catch(Exception $ex) {
  echo "catched Exception\n";
}
echo "done.";

The result of compilation can be found here: http://ideone.com/6KATXQ

You see: "Inside of method_a()" is output as well as "done".
So, I've appeared inside of method_a(), wile shouldn't and at same time didn't catch any exception.

Uncommenting Line 7 will interrupt execution, but still will not throw any exception.
And only line 5 will make catch() block work.

Actions #5

Updated by Markus Klein over 9 years ago

thanks for the example, sorry, I mixed things up here.

The error handler actually creates the exception first hand. It captures the php error and converts it to an exception.
Of course it is not so easy to catch this exception.

Actions #6

Updated by Viktor Livakivskyi over 9 years ago

Markus, thank you for the note, but this is only partly true.

Exception is created by ErrorHandler only in case, which can be seen here: https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_6-1/typo3/sysext/core/Classes/Error/ErrorHandler.php#L94-L109

But with [SYS][displayErrors] = 2, $this->exceptionalErrors becomes '0', so the 'if' condition from the code of ErrorHandler doesn't work and we land to 'else', which only writes log and returns 'TRUE' and so the code continues execution and no exception can be caught.

Therefore the minimum fix, which can be provided here: do not always return TRUE.

Maybe, do something, like this:

switch ($errorLevel) {
    case E_USER_ERROR:
    case E_RECOVERABLE_ERROR:
        return FALSE;

    case E_USER_WARNING:
    case E_WARNING:
    default:
        return TRUE;
}

BTW, same happens with 6.2 too, as I can see from the code.

Actions #7

Updated by Markus Klein over 9 years ago

Hi!

I read through the whole code now (6.3) and agree that it is a mess.

Basically we have to deal with two things: Errors (generated by PHP parser) and Exceptions (generated by code).

The options for [SYS][displayErrors] and what they really do: * -1 TYPO3 does not touch the PHP setting 'display_errors', but still converts most errors into exceptions, which are handled by the registered exceptionHandler then. If the devIPmask matches, exceptions are shown using the debugExceptionHandler for more details. * 0 TYPO3 sets PHP setting display_errors to 0, so no PHP errors are shown in FE. Moreover no error is converted into an exception, so the errorHandler will handle all of them. * 1 TYPO3 sets PHP setting display_errors to 1, so PHP errors are shown in FE. Most errors will be converted to exceptions and will be handled by the debugExceptionHandler. * 2 If devIPmask matches [SYS][displayErrors] is set to 1, otherwise to 0

At any configuration execution must be stopped in case of a non-user error.

Notes: Setting '1' will also display the error as a flash message, if it isn't converted to an exception.

I'll push a cleanup of the code first and we can discuss further solutions then.

Actions #8

Updated by Markus Klein over 9 years ago

I created another ticket for the cleanup: #61235

Actions #9

Updated by Gerrit Code Review over 9 years ago

  • Status changed from New to Under Review

Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/32465

Actions #10

Updated by Viktor Livakivskyi over 9 years ago

Many thanks for fast patching!

Tested under same conditions - all looks good for me.

Actions #11

Updated by Gerrit Code Review over 9 years ago

Patch set 2 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/32465

Actions #12

Updated by Gerrit Code Review over 9 years ago

Patch set 3 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/32465

Actions #13

Updated by Gerrit Code Review over 9 years ago

Patch set 1 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/33491

Actions #14

Updated by Gerrit Code Review over 9 years ago

Patch set 1 for branch TYPO3_6-1 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/33492

Actions #15

Updated by Markus Klein over 9 years ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100
Actions #16

Updated by Benni Mack over 5 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF