How to Catch a "Catchable Fatal Error" on PHP Type Hinting

How can I catch a catchable fatal error on PHP type hinting?

Update: This is not a catchable fatal error anymore in php 7. Instead an "exception" is thrown. An "exception" (in scare quotes) that is not derived from Exception but Error; it's still a Throwable and can be handled with a normal try-catch block. see https://wiki.php.net/rfc/throwable-interface

E.g.

<?php
class ClassA {
public function method_a (ClassB $b) { echo 'method_a: ', get_class($b), PHP_EOL; }
}
class ClassWrong{}
class ClassB{}
class ClassC extends ClassB {}

foreach( array('ClassA', 'ClassWrong', 'ClassB', 'ClassC') as $cn ) {
try{
$a = new ClassA;
$a->method_a(new $cn);
}
catch(Error $err) {
echo "catched: ", $err->getMessage(), PHP_EOL;
}
}
echo 'done.';

prints

catched: Argument 1 passed to ClassA::method_a() must be an instance of ClassB, instance of ClassA given, called in [...]
catched: Argument 1 passed to ClassA::method_a() must be an instance of ClassB, instance of ClassWrong given, called in [...]
method_a: ClassB
method_a: ClassC
done.

Old answer for pre-php7 versions:

http://docs.php.net/errorfunc.constants says:

E_RECOVERABLE_ERROR ( integer )

Catchable fatal error. It indicates that a probably dangerous error occured, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR.

see also: http://derickrethans.nl/erecoverableerror.html

e.g.

function myErrorHandler($errno, $errstr, $errfile, $errline) {
if ( E_RECOVERABLE_ERROR===$errno ) {
echo "'catched' catchable fatal error\n";
return true;
}
return false;
}
set_error_handler('myErrorHandler');

class ClassA {
public function method_a (ClassB $b) {}
}

class ClassWrong{}

$a = new ClassA;
$a->method_a(new ClassWrong);
echo 'done.';

prints

'catched' catchable fatal error
done.

edit: But you can "make" it an exception you can handle with a try-catch block

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

class ClassA {
public function method_a (ClassB $b) {}
}

class ClassWrong{}

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

see: http://docs.php.net/ErrorException

PHP: How do I fix this type hinting error?

From the manual

Typed pass-by-reference Parameters

Declared types of reference parameters are checked on function entry, but not when the function returns, so after the function had returned, the argument's type may have changed.

Given you are immediately assigning a new value to $output, its type declaration is irrelevant. Either omit the type declaration or mark it nullable

function foo(int $one, int $two, ?int &$output): void
{
$output = $one + $two;
}

https://3v4l.org/j91DG


Of course, this type of pattern is convoluted and makes no sense over something as simple as

function foo(int $one, int $two): int
{
return $one + $two;
}

How to ignore a PHP catchable fatal error from QueryPath?

It's a catchable fatal error .. so catch it.

If you catch it you can get a full stacktrace.

Ex:

try {
thisfunctionthrowsanexception();
} catch (Exception $e) {
var_dump(get_class($e));
echo $e->getTraceAsString();
}

@ hides errors. You don't ever want to have to use that.

PHP type hinting error?

Since this could be misleading and since this answer is still quite high in search engines.

PHP 7 did introduce type hinting for scalar types

There is no scalar type hinting in PHP 5, so the integer type hint is considered to be a class type hint.

More reference http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration

PHP: Type hinting in namespaces not working?

It is not possible to typehint strings in PHP 5.6. Support for this feature was added in PHP 7.

More info on typehinting for functions in PHP.

Inexplicable type hinting in PHP code

You mention that there is no use statement or namespace declaration that alludes to a 'string' class in the code. Does the code use an Autoloader?

Two possible issues at hand here:

Paths - It is possible that the live environment has another path set up, and/or that a file/class is being loaded/searched for via this 'other path' (outside the code you may be looking at).

Error Handling - Another possible cause is if there is an error handler in the production environment that always returns true.

I had this exact issue where a type-hint wasn't resolving in development, but I didn't realize until we pushed it live and the error handler was no longer registered.

Obviously a fatal parse error can not be stopped, but it turns out a catch-able error can be ignored if the error handler returns true. And this is what I am putting my money on in your case.

Additionally, it is very important to note that there is no way to type-hint a scalar, as one user pointed out.

A simpler way to say it is "it is not possible to type-hint anything that can be represented by a string." This is due to the way in which PHP handles it's more primitive variables, they can all be type-cast to one another, and therefore (because 1, "1" and true can all be == 1, == '1' and == true) it is not actually possible for the interpreter as it is written to actually catch and enforce scalar type-hints.

Answer this question: Is that variable supposed to be $str = "something"; or $str = new string(); (ie, a string or an object)?

If it is supposed to be a string, remove the type-hint, as nothing in PHP allows this support (save for HHVM, but you would know this if you were using it).

Since you say you do not have access to the code, I suggest notifying someone who does.

catchable fatal error explanation

 mysqli_query ($dbc. $SQLanswered)

Shouldn't that be

  mysqli_query ($dbc, $SQLanswered)

?

Looks like you're accidentally doing string concatenation.



Related Topics



Leave a reply



Submit