2

I understand the significance of the term 'fatal error', but I want to write a test class like this (disgustingly simplified):

class tester {

    function execute() {

        if( @$this->tryit() === true ) return true;
        return false;

    }

    function tryit() {

        $doesntexist = new noobject();
        return true;

    }

}

actually I'd have a Test parent class, and then classes would extend it and contain a bunch of methods with a bunch of tests. The parent class would define execute and it would just run every method in the child class (excluding execute of course) and collecting data on which functions pass and which fail.

I want to write tests before I actually write part of my code, but instead of using assert I just want to run every test and generate a list of which functions of which test classes fail. But that means if a test fails it means there was an error -- but I also want to handle instances where I forgot to define a class, etc. Is it possible to do that, while not having the entire script die?

I was thinking that the script would just fail up until the function call with the @ in front of it, and then continue, but obviously I was wrong. Is there a workaround?

5 Answers 5

7

A fatal error is fatal, and there is nothing you can do about it.

Two ideas of solutions could be :

  • To test if the method exists before trying to call it ; see method_exists
  • Or, to run each "test" in a separate processus : this way, if there is a Fatal Error caused by one test, only the "child" process corresponding to that test dies, and the "parent" process, the test launcher, can detect this and consider it as a failure.

Actually, the second solution exists in PHPUnit since version 3.4, if I remember correctly ;-)

2

Fatal errors cannot be stopped, not even with set_error_handler. However, you can often find another way at the expense of writing more code. For the example method tryit, you can write an autoload function that triggers a non-fatal error or (in PHP 5.3.0) throws an exception, or use class_exists to skip the instantiation of a non-existent class.

2

Yes and No

You cannot write it so that the code picks up where it left off, after the fatal. However, you can use register_shutdown_function() to continue processing php after the fatal error.

I've written code that checks which kind of fatal error it was and then attempt to fix it before redirecting the user back to the same page, or dying.

register_shutdown_function is excellent for redirecting the user to a 500 error page with a contact form prevalued with the error info. This way I could have the users help me out by opening an issue on my github acct.

1

I'm guessing you would set up an error handler with the set_error_handler() function that calls into your testing class to report an error, but I'm not entirely sure exactly how you'd implement it.

2
  • will fatal errors go through the error handler? From reading further, it seems like you can only get a-hold of them by registering a shutdown function... Commented Dec 18, 2009 at 5:15
  • That's what the docs indicated, but I suppose it was just ambiguous wording on their part. Commented Dec 18, 2009 at 5:28
-1

With PHP 7, you can now try/catch a fatal error.

https://www.php.net/manual/en/language.exceptions.php

1
  • Please demonstrate how to catch a fatal error to prove your claim. A minimal 3v4l.org demo will suffice. Commented Mar 24, 2022 at 22:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.