Общее Исключение

всем привет

не могу догнать — как оптимальным образом вызывать исключение для всех методов контроллера

работает сейчас так: сначала определяю общий метод-обработчик ошибок для конкретного контроллера


public function init() {        

  parent::init();

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

}

а затем в нужном методе вбрасываю исключение


if(Yii::app()->user->isGuest)throw new CHttpException('403','просмотр контента запрещен');

естественно: ломает в каждом методе прописывать эту строку

попробовал в конструкторе вбросить - не подцепился общий дизайн: на белом листе прочитал свое сообщение…

нужен хелп!

может вам это нужно

http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth#sec-5

ммм… а как я в accessRules реализую вброс исключения?

хочется-то управлять содержанием страницы в определенном месте

Какая цель?

Для ошибок можно определить страницу в config/main.php


        'errorHandler' => array(

            'errorAction' => 'site/error',

        ),

уточните задачу

Есть такая штука как beforeAction. Это если вам нужно для 1 контроллера, а если больше используйте фильтр.

А еще все контролеры наследуются от components/Controller, наверняка в нем можно объявить beforeAction который также унаследуется всеми контроллерами приложений.

Совершенно верно. Это просто я не любитель всех этих наследований поэтому пишу прямо в контроллере локально.

to ineersa и Charger, спасибо за подсказку, но это я уже пробовал - что правильнее: генерить в бифоЭкшн или в конструкторе - пока обсуждать рано

тут вскрылась другая проблема, совершенно для меня загадошная

  1. если я вбрасываю исключение непосредственно в экшене, то текст исключения выводится в нужном дизайне, на основании установки errorHandler и errorAction - хоть в майн-конфиге, хоть в инит-методе контроллера, хоть на лету в бифоЭкшн

  2. но если я генерю исключение в бифоЭкш или конструкторе (т.е. НЕ в экшене), то текст исключения выводится или в дизайне errorHandler - errorAction - site/error или вообще без дизайна = на белой странице,

то есть если обработчик ошибок не в контроллере Site - дизайн не применяется

такое впечатление, что во втором случае теряются пути к лайаутам или еррор-виду, поэтому и белый лист

в чем засада?

спасибо, я и это пробовал - проблема уже не в способе применения исключения ко всем экшенам, а в корректном отображении текста исключения в нужном дизайне

А это где например?

И еще, уверены, что используете CHttpException а не CException?

вот что выводится на экран без дизайна

Что-то я запутался. Пытаюсь представить ваш код и наверное представляю что то не то.

Я предположил, что "НЕ в экшене" означает кидание исключения в моделе. А на самом деле идет речь про конструктор контроллера или его же beforeAction.

Кстати точно такую же проблему поднимали в мае на англ. форуме толком решения нет, просто решили рендерить ‘site/error’

О! и в апреле безответный пост на русском

Сам я не сталкивался с такой задачей, к сожалению. Не подключается layout, на правах догадки, если в beforeAction перед выбросом исключения сделать


$this->layout='main'

?

  1. толком решения нет, просто решили рендерить ‘site/error’ = такая мысль посещала, но не хотелось бы в экшене сайта делать условия…

  2. склоняюсь к формированию общих для всех сайтов страниц ошибок посредством набора страниц errorXXX - в едином дизайне и отключении дибаг режима

p.s. вообще какая-то косячная тема = реально мозгов не хватило чтобы понять суть происходящего

p.s.2 = может samdark поможет? ау!

Или я чего то не понимаю,или вы делаете что то не так. У меня все прекрасно работает.

Вот например:




public function beforeAction($action)

    {

        if (parent::beforeAction($action)) {

        	$handler=Yii::app()->getErrorHandler();

		$handler->errorAction='site/error';//можна задать свою страничку с ошибками

           if ($action->id!='error') {

                throw new CHttpException(403, 'error check');

                return false;

            }

            return true;

        }else{

            return false;

        }

	}

//Сам action с ошибкой

public function actionError()

	{

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

		{

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

				echo $error['message'];

			else

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

		}

	}

//Ну и в view

<h2>Error <?php echo $code; ?></h2>


<div class="error">

<?php echo CHtml::encode($message); ?>

</div>



Данный код замечательно работает и отображается в layout контроллера.

тут второе ;D

вот этот ваш код =


public function beforeAction($action)

{

  if (parent::beforeAction($action))

  {

    $handler=Yii::app()->getErrorHandler();

    $handler->errorAction='my/error';

    if ($action->id!='error')

    {

      throw new CHttpException(403, 'beforeAction доступ запрещен');

      return false;

    }

    return true;

  }

  else

  {

    return false;

  }

}

совершенно рабочий! спасибо ineersa

только непонятно, а зачем такое условие =


if (parent::beforeAction($action))

{

  ...

}

и еще, что хотелось бы отметить: без этого условия =


if ($action->id!='error')

{

  throw new CHttpException(403, 'beforeAction доступ запрещен');

  return false;

}

работать не будет = опять будет текст исключения на белой странице

видать мой просчет был в том, что я не применял проверку на айдишник экшена и [color="#8B0000"]исключение применялось и к экшенЕррору тоже[/color]

вот как было у меня =


protected function beforeAction($action) 

{          

  throw new CHttpException(403, 'beforeAction доступ запрещен');

  return parent::beforeAction($action);

}

а надо было так =


protected function beforeAction($action) 

{          

  if ($action->id!='error')

  {

    throw new CHttpException(403, 'beforeAction доступ запрещен');

    return false;

  }

  return parent::beforeAction($action);

}

из ит тру?

Это вызов метода предка и проверка, что он вернул true. Как минимум хороший тон, не забывать вызывать “предков” :)