We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Catching fatal errors on type hinted controller methods

Hello,

I have the following router converter defined:


    $router->addGet(...)
    ->convert('southWest', function($southWest) {
        $sw = explode(',', $southWest);
        try{
            $p = new Point($sw[0], $sw[1]);
        } catch(Exception $e) {
            //Impossible to create instance of Point and senseless to use default values
            $p = NULL
        }
        return $p;
    });

The parameter (Point) will be passed to the following controller method:

    public function fooAction(Point $southWest) {
        ...mycode
    }

In case of an Exception inside the converter, $p = NULL will be returned and then passed to fooAction. Unfortunately then a Catchable fatal error will be thrown by PHP.

Now my questions:

Is it possible to redirect to another action before fooAction will be called with a invalid parameter ? Is it possible to catch the fatal error and call another action? If yes, where should that be done?



98.9k

I think those fatal E_RECOVERABLE_ERROR errors cannot be catched by a try/catch:

try {
  class X
  {
          public function b(X $x)
          {
          }
  }

  $a = null;
  $x = new X;
  $x->b($a);
} catch (\Exception $e) {
    // this is never executed
}
PHP Catchable fatal error:  Argument 1 passed to X::b() must be an instance of X, null given, called in /Users/scott/cphalcon/a.php on line 13 and defined in /Users/scott/cphalcon/a.php on line 6

You can create an error handler to handle these kind of errors:

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


8.6k

Yes, indeed. They can not be catched. I was hoping there is a build in way in phalcon that makes it possible to elegantly call/redirect to another action in that case. I'll then take another way and send an invalid request response right from the catch block before die()ing.

Thanks



3.1k
edited Oct '14

How about:

$sw = explode(',', $southWest)
try {
    $p = new Point($sw[0], $sw[1]);
    if(!get_class(p) === Point) {
        // call other action here
    }
} catch(Exception $e) {
    //Impossible to create instance of Point and senseless to use default values
    $p = NULL
}
return $p;

?



8.6k
edited Oct '14

My point class will throw an exception when coordinates are invalid (e.g. 837.23472,-414.128371). I can't do that.

edited Aug '18

My point class will throw an exception when coordinates are invalid (e.g. 837.23472,-414.128371). I can't do that.

in PHP7 now you can using try catch to catch up PHP FATAL ERROR try this:

try {
do somethings will raise falta error
} catch (Error $e) {
now you can catch me :)
}

Hope this help!