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?



84.5k

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;
})


5.3k

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



1.9k
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;

?



5.3k
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.