[SOLVED] Dispatcher has detected a cyclic routing causing stability problems - Phalcon
I was recently working on a Phalcon project and came across this error "Dispatcher has detected a cyclic routing causing stability problems" while trying to restrict access to some controllers. Apparently this looks like an unending loop.
Doing some more research I saw this "If the dispatch loop makes more than 256 loops it throws this exception. Normally this is caused because the application continue making forwards over and over without exiting the dispatch loop. https://github.com/phalcon/cphalcon/blob/2.0.0/phalcon/dispatcher.zep#L378".
Here is the code that was giving the issue
namespace Blog\Controllers\Admin;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class ControllerBase extends Controller
{
public function afterExecuteRoute()
{
$this->view->setViewsDir($this->view->getViewsDir() . 'admin/');
}
/**
* Execute before the router so we can determine if this is a provate controller, and must be authenticated, or a
* public controller that is open to all.
*
* @param Dispatcher $dispatcher
* @return boolean
*/
public function beforeExecuteRoute(Dispatcher $dispatcher)
{
$controllerName = $dispatcher->getControllerName();
// Get the current identity
$identity = $this->auth->getIdentity();
// If there is no identity available the user is redirected to index/index
if (!is_array($identity)) {
$dispatcher->forward(array(
'namespace' => 'Blog\Controllers\Admin',
'controller' => 'accounts',
'action' => 'login'
));
return false;
}
return;
}
}
The challenge was because all my controllers extended this base controller, so it keeps looping in cycle. The solution is to exclude the controller you are forwarding your dispatcher to. I added a condition that excluded the controller.
namespace Blog\Controllers\Admin;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class ControllerBase extends Controller
{
public function afterExecuteRoute()
{
$this->view->setViewsDir($this->view->getViewsDir() . 'admin/');
}
/**
* Execute before the router so we can determine if this is a provate controller, and must be authenticated, or a
* public controller that is open to all.
*
* @param Dispatcher $dispatcher
* @return boolean
*/
public function beforeExecuteRoute(Dispatcher $dispatcher)
{
$controllerName = $dispatcher->getControllerName();
// Get the current identity
$identity = $this->auth->getIdentity();
// If there is no identity available the user is redirected to index/index
if (!is_array($identity) && ($controllerName != "accounts")) {
$dispatcher->forward(array(
'namespace' => 'Blog\Controllers\Admin',
'controller' => 'accounts',
'action' => 'login'
));
return false;
}
return;
}
}
I hope this helps someone greatly.