Null Handler, Probably For 'saveglobalstate'

I regularly, but not constantly, get the following error message for a Yii Console application (Yii 1.1.12):




exception 'CException' with message 'L'événement « CConsoleApplication.onendrequest » est associé à  un gestionnaire d'événement « NULL » invalide.' in /home/www/public_html/yii/framework/base/CComponent.php:568

Stack trace:

#0 /home/www/public_html/yii/framework/base/CApplication.php(201): CComponent->raiseEvent('onEndRequest', Object(CEvent))

#1 /home/www/public_html/yii/framework/base/CApplication.php(164): CApplication->onEndRequest(Object(CEvent))

#2 /home/www/public_html/yii/framework/yiic.php(34): CApplication->run()

#3 /home/www/public_html/app/protected/yiic.php(7): require_once('/home/www/publi...')



for the following throw call in CComponent:




throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',

    array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>gettype($handler))));



So ‘gettype’ for ‘$handler’ is NULL.

That is strange because that seems to imply that attachEventHandler was called with $handler as ‘NULL’.

In my app, I only have YAPNS attaching an event on ‘onEndRequest’ like this:




    \Yii::app()->attachEventHandler('onEndRequest', array($this, 'onApplicationEndRequest'));



In the Yii code:

  • ‘CApplication’ attaches the following event:



$this->attachEventHandler('onEndRequest',array($this,'saveGlobalState'));



  • ‘CLogRoute’ attaches:



Yii::app()->attachEventHandler('onEndRequest',array($this,'processLogs'));



CApplication has a ‘detachEventHandler’ call for ‘saveGlobalState’ when ‘saveGlobalState’ is called.

I call ‘setGlobalState’ in my application, and I may call it two times.

These are all arrays, so never NULL and ‘gettype’ should say ‘array’.

My best guess at why I get NULL is this:

  • the ‘saveGlobalState’ handler is added multiple times to the event handler list.

  • As the ‘saveGlobalState’ handler removes itself from the list,the ‘$this->_e[$name]’ in ‘CComponent::raiseEvent’ is “tampered” with during the execution of the loop to call the handlers.

  • When the second or higher entry is called, the ‘$handler’ is NULL.

Solution:

  • Workaround: call ‘saveGlobalState’ explicitly instead of letting Yii handling this a the end of the processRequest.

  • Permanent solution: would require change of Yii.

Just a quick followup note with good news.

I have non more issues since I applied the workaround (call saveGlobalState explicitally).

So it looks like my assumption is correct and that the workaround does the job ;-).