Custom errorHandler for specific controller

Hi,

Is there any way to define component errorHandler for specific controller?

I have defined error handler in main.php for my Frontend:




	'errorHandler'=>array(

            'errorAction'=>'/site/index/error',

        ),



I can specify custom errorHandler for each module in init() method and that working fine:




		Yii::app()->setComponents(array(

	        'user'=>array(

                'allowAutoLogin'=>false,

                'stateKeyPrefix'=>'admin_',

                'loginUrl'=>Yii::app()->createUrl('/admin/index/login'),

	        ),

			'errorHandler'=>array(

	            'errorAction'=>'/admin/index/error',

	        ),	        

		));	



Also in beforeControllerAction() of each module:




				Yii::app()->setComponents(array(

					'user'=>Yii::app()->getModule('admin')->getComponents(true),

				));



But if I try to set a errorHandler in beforeControllerAction() that not works.

Application don’t even trigger this action - that is logically, I guess.

Is there any way to figure it out? Or another way - could I get controller id in module init() method in any way?

You can specify custom errorHandler for each controller in init() if you want, why not?

something like the following would work for your case

define you error it as relative:


'errorHandler'=>array(

            'errorAction'=>'error',

        ),

then define a general error action, something like


class Controller extends CController{

//your code here

    public function actionError()     {         if($error=Yii::app()->errorHandler->error)         {             if(Yii::app()->request->isAjaxRequest)                 echo $error['message'];             else                 $this->render('//error', $error);         }     } 

}

and then in the controllers you want to have a different error handler override the action error

That shoul do it

Doesn’t work :(

CErrorHandler:




		if($view==='error' && $this->errorAction!==null)

			Yii::app()->runController($this->errorAction);

		else

		{

			// additional information to be passed to view

			$data['version']=$this->getVersionInfo();

			$data['time']=time();

			$data['admin']=$this->adminInfo;

			include($this->getViewFile($view,$data['code']));

		}



trace:

#0 E:\PHP\kodinocms\yii\base\CErrorHandler.php(279): CWebApplication->runController(‘error’)

#1 E:\PHP\kodinocms\yii\base\CErrorHandler.php(178): CErrorHandler->render(‘error’, Array)

#2 E:\PHP\kodinocms\yii\base\CErrorHandler.php(103): CErrorHandler->handleException(Object(CHttpException))

#3 E:\PHP\kodinocms\yii\base\CApplication.php(631): CErrorHandler->handle(Object(CExceptionEvent))

#4 [internal function]: CApplication::handleException(Object(CHttpException))

#5 {main}

Seems to if is only ‘error’ declared in errorHandler, Yii is trying to run ‘error’ controller…

Any other ideas?

Yea, I did that once, I just dont remember how to set it

I deal with that. Solution is set ‘errorAction’ in init() method of controller which extends controllers haved custom error action. Solved.

My solution:




class ApiController extends Controller {

    public function init() {        

        parent::init();

        Yii::app()->errorHandler->errorAction='api/error';

    }

    public function actionError(){

        echo json_encode(array(

            'Status'=>500,

            'Message'=>'Unknown error'

        ));

    }



My AdminController extends CController


/**

 	* @var set own Error file for the backend

 	*/

	public function init() {

    	parent::init();

    	Yii::app()->errorHandler->errorAction= $this->actionError();

	}


	/**

 	* This is the action to handle external exceptions.

 	*/

	public function actionError()

	{

    	if($error=Yii::app()->errorHandler->error)

    	{

        	if(Yii::app()->request->isAjaxRequest)

            	echo $error['message'];

        	else

            	$this->render('/admin/error', $error);

    	}

	} 

My solution (just in case):




class ErrorHandler extends CErrorHandler

{

	protected function render($view,$data)

	{

		$controller=Yii::app()->controller;

		if(method_exists($controller, 'actionError'))

			$controller->run('error');

		else

			parent::render($view, $data);

	}

}



config:




	'components'=>array(

		'errorHandler'=>array(

			// use 'site/error' action to display errors

			'errorAction'=>'site/error',

			'class'=>'ErrorHandler',

		),



So, you need specify actionError() to handle error in custom controller.




class JsonApiController extends CController

{

...

	public function actionError()

	{

		if($error=Yii::app()->errorHandler->error)

		{

			$error=array(

				'code'=>$error['code'],

				'message'=>$error['message'],

			);

			echo CJSON::encode($error);

		}

	}

}