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

How to display error 404 page in multi modules using main error controller?

I can't make not found error page.

router.php

$router = new Phalcon\Mvc\Router();

$router->removeExtraSlashes(true);

// required for modules.
$router->setDefaultModule('core');

$router->add(
    '/{lang:[a-z]{2}}/index/:action/:params',
    array(
        'module' => 'core',
        'controller' => 'index',
        'action' => 2,
        'params' => 3,
    )
);
$router->add(
    '/{lang:[a-z]{2}}', 
    array(
        'module' => 'core',
        'controller' => 'index',
        'action' => 'index',
    )
);

services.php

// set dispatcher
$di->set('dispatcher', function() use ($di) {
    $evManager = $di->getShared('eventsManager');

    $evManager->attach('dispatch:beforeException', function($event, $dispatcher, $exception) {
        switch ($exception->getCode()) {
            case PhDispatcher::EXCEPTION_HANDLER_NOT_FOUND:
            case PhDispatcher::EXCEPTION_ACTION_NOT_FOUND:
                $dispatcher->forward(
                    array(
                        'module' => 'core',
                        'controller' => 'error',
                        'action' => 'e404',
                    )
                );
                return false;
        }
    });

    $dispatcher = new PhDispatcher();
    $dispatcher->setEventsManager($evManager);
    $dispatcher->setDefaultNamespace('Core\\Controllers');
    return $dispatcher;
});

index.php

$application = new \Phalcon\Mvc\Application($di);
    $application->registerModules(
        array(
            'core' => array(
                'className' => 'Core\\Module',
                'path' => APPFULLPATH . '/Module.php',
            ),
            'contact' => array(
                'className' => 'Modules\\Contact\\Module',
                'path' => ROOTFULLPATH . '/modules/contact/Module.php',
            )
        )
    );

Request the page to /index/action-not-exists action-not-exists is not exists in the index controller. but it is not forward to error page.

"Action 'action-not-exists' was not found on handler 'index'"

This is what i got instead of my 404 page.

How to make 404 error page and use in all modules?

--

update: 01

My source code are here https://github.com/OkveeNet/phalcon-begins

Now i can manage to display error 404 page But i have to add this code in every modules. https://github.com/OkveeNet/phalcon-begins/blob/master/core/Module.php

How to make it work in All modules at once? or How to make it use only main settings?

--

Dear Phalcon, please make it easier to manage error pages just like other frameworks.

edited Mar '15

use this simple solution instead (just add notFound route to your router):

$router = new Phalcon\Mvc\Router();

// add routes .....

$router->notFound(array(
  'module' => 'default',
  "controller" => "error",
  "action" => "notFound"
));

// blah blah blah ....

$di->set('router', $router);


6.2k

use this simple solution instead (just add notFound route to your router):

$router = new Phalcon\Mvc\Router();

// add routes .....

$router->notFound(array(
 'module' => 'default',
 "controller" => "error",
 "action" => "notFound"
));

// blah blah blah ....

$di->set('router', $router);

No, it is not working.

What is your phalcon version?!!!

I've used this method in more that 5 production project by Phalcon 2.0!!!

for example check by this App https://beta.abplus.ir and add any path you want like https://beta.abplus.ir/blahblahblah



6.2k

I'm using Phalcon 1.3.4.

However i'm using dynamic router and multi module and language uri.

Maybe exception code is not the expected, it could also be

Dispatcher::EXCEPTION_NO_DI
Dispatcher::EXCEPTION_CYCLIC_ROUTING
Dispatcher::EXCEPTION_INVALID_HANDLER
Dispatcher::EXCEPTION_INVALID_PARAMS


6.2k
edited Mar '15
// set dispatcher
$di->set('dispatcher', function() use ($di) {
    $evManager = $di->getShared('eventsManager');

    $evManager->attach('dispatch:beforeException', function($event, $dispatcher, $exception) {
        exit;
        switch ($exception->getCode()) {
            case PhDispatcher::EXCEPTION_HANDLER_NOT_FOUND:
            case PhDispatcher::EXCEPTION_ACTION_NOT_FOUND:
                $dispatcher->forward(
                    array(
                        'module' => 'core',
                        'controller' => 'error',
                        'action' => 'e404',
                    )
                );
                return false;
        }
    });

    $dispatcher = new PhDispatcher();
    $dispatcher->setEventsManager($evManager);
    $dispatcher->setDefaultNamespace('Core\\Controllers');
    return $dispatcher;
});

It is not even exit.


The question updated.



6.2k

Hello, i am still cannot make 404 on controller, module not found to work. Can anyone help me? please.

edited Mar '15

This is my 404 handling code that works perfectly before using the method that i mentioned in my previous post. you can try this one too.

        $dispatcher    = new \Phalcon\Mvc\Dispatcher();
        $eventsManager = new \Phalcon\Events\Manager();

        $eventsManager->attach("dispatch", function ($event, $dispatcher, $exception) use ($di) {
                if ($event->getType() == 'beforeNotFoundAction') {
                    $di->get('response')->redirect('site/error/notFound');

                    return false;
                }

            if ($event->getType() == 'beforeException') {
                    switch ($exception->getCode()) {
                        case \Phalcon\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                        case \Phalcon\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
                            $di->get('response')->redirect('site/error/notFound');
                            return false;
                        default:
                            $di->get('response')->redirect('site/error/internalError');
                            return false;
                    }
                }

            });

        $dispatcher->setEventsManager($eventsManager);
        $di->setShared('dispatcher', $dispatcher);


6.2k
edited Mar '15

This is my 404 handling code that works perfectly before using the method that i mentioned in my previous post. you can try this one too.

      $dispatcher    = new \Phalcon\Mvc\Dispatcher();
      $eventsManager = new \Phalcon\Events\Manager();

      $eventsManager->attach("dispatch", function ($event, $dispatcher, $exception) use ($di) {
              if ($event->getType() == 'beforeNotFoundAction') {
                  $di->get('response')->redirect('site/error/notFound');

                  return false;
              }

          if ($event->getType() == 'beforeException') {
                  switch ($exception->getCode()) {
                      case \Phalcon\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                      case \Phalcon\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
                          $di->get('response')->redirect('site/error/notFound');
                          return false;
                      default:
                          $di->get('response')->redirect('site/error/internalError');
                          return false;
                  }
              }

          });

      $dispatcher->setEventsManager($eventsManager);
      $di->setShared('dispatcher', $dispatcher);

From my latest source code here https://github.com/OkveeNet/phalcon-begins

I can make it work about...

not found module\controller -> 404 error page.

not found module\controller\action -> 404 error page.

But not found module or [module is not registered] to 404 error page still does not working.

$di->set('dispatcher' is not working for "module is not registered"!



6.2k

For module ... is not registered. I tried to use catch {...} to match error message because there is no support from Phalcon about module not registered error.

try {
    echo $application->handle()->getContent();
} catch (\Exception $e) {
        if (preg_match('/Module (.*) is not registered/ius', $e->getMessage()) == 1) {
        $dispatch = $di->getShared('dispatch');
        $dispatcher->forward(
            array(
                'namespace' => 'Core\\Controllers',
                'module' => 'core',
                'controller' => 'error',
                'action' => 'e404',
            )
        );
        return false;
    }
}

But i'm still cannot send it to use Error controller. Does anyone help?