ZF-12435: Passing an exception as the message to Zend_Log_Writer_Db raises an exception
Description
The other log writers allow you to pass an instance of an exception as the message for logging. In particular, Zend_Log_Writer_Firebug even has a formatter that renders in a way that is easy to read when debugging XmlHttpRequests. However, I get an exception in Zend_Log_Writer_Db because the message is an object:
{panel:title=Exception} exception 'Zend_Db_Statement_Sqlsrv_Exception' with message 'An invalid PHP type for parameter 4 was specified.' in ..\library\Zend\Db\Statement\Sqlsrv.php:206 Stack trace:
0 ..\library\Zend\Db\Statement.php(320): Zend_Db_Statement_Sqlsrv->_execute(Array)
1 ..\library\Zend\Db\Adapter\Abstract.php(479): Zend_Db_Statement->execute(Array)
2 ..\library\Zend\Db\Adapter\Sqlsrv.php(380): Zend_Db_Adapter_Abstract->query('INSERT INTO "Ap...', Array)
3 ..\library\Zend\Log\Writer\Db.php(143): Zend_Db_Adapter_Sqlsrv->insert('ApplicationLog', Array)
4 ..\library\Zend\Log\Writer\Abstract.php(85): Zend_Log_Writer_Db->_write(Array)
5 ..\library\Zend\Log.php(428): Zend_Log_Writer_Abstract->write(Array)
6 [internal function]: Zend_Log->log(Object(Exception), 3)
7 ..\library\My\Controller\Plugin\Log.php(212): call_user_func_array(Array, Array)
8 [internal function]: My_Controller_Plugin_Log->__call('log', Array)
9 [internal function]: My_Controller_Plugin_Log->log(Object(Exception), 3)
10 ..\library\My\Controller\Action\Helper\Log.php(27): call_user_func_array(Array, Array)
11 ..\application\controllers\ErrorController.php(52): My_Controller_Action_Helper_Log->__call('log', Array)
12 ..\application\controllers\ErrorController.php(52): My_Controller_Action_Helper_Log->log(Object(Exception), 3)
13 ..\library\Zend\Controller\Action.php(516): ErrorController->errorAction()
14 ..\library\Zend\Controller\Dispatcher\Standard.php(295): Zend_Controller_Action->dispatch('errorAction')
15 ..\library\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
16 ..\library\Zend\Application\Bootstrap\Bootstrap.php(97): Zend_Controller_Front->dispatch()
17 ..\library\Zend\Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
18 ..\public\index.php(126): Zend_Application->run()
19 {main}
{panel}
I can pass the exception in as a string, but then it is more difficult to read in Firebug. I'm also not sure if this problem is specific to the database adapter I am using (Zend_Db_Adapter_Sqlsrv) since I don't have another database/adapter I can test right now.
I think a change in Zend_Log_Writer_Db::_write() should fix it but I don't know if it might raise other issues:
/**
* Write a message to the log.
*
* @param array $event event data
* @return void
* @throws Zend_Log_Exception
*/
protected function _write($event)
{
if ($this->_db === null) {
// require_once 'Zend/Log/Exception.php';
throw new Zend_Log_Exception('Database adapter is null');
}
if ($this->_columnMap === null) {
$dataToInsert = $event;
} else {
$dataToInsert = array();
foreach ($this->_columnMap as $columnName => $fieldKey) {
- $dataToInsert[$columnName] = $event[$fieldKey];
+ if ('info' == $fieldKey && (is_object($event[$fieldKey]) || is_array($event[$fieldKey]))) {
+ $dataToInsert[$columnName] = Zend_Debug::dump($event[$fieldKey], gettype($event[$fieldKey]), true);
+ } else {
+ $dataToInsert[$columnName] = $event[$fieldKey];
+ }
}
}
$this->_db->insert($this->_table, $dataToInsert);
}
I tried to resolve this by extending Zend_Log_Writer_Db to override the _write method, but all of the properties are marked private instead of protected for some reason. As a result, getting it to work would have required duplicating the entire class. (If they truly need to be private, perhaps the class should be final?)
Comments
Posted by Andrew Ballard (aballard) on 2012-10-04T16:54:23.000+0000
Fixed code block.
Posted by Frank Brückner (frosch) on 2013-02-15T07:01:44.000+0000
Hi Andrew, I will look into your problem with exceptions. I must write a unit test.
{quote} tried to resolve this by extending Zend_Log_Writer_Db to override the _write method, but all of the properties are marked private instead of protected for some reason.{quote} This problem was fixed with ZF-12514. (Look at the diff)
Thanks for your help! :)
Posted by Andrew Ballard (aballard) on 2013-02-15T17:40:24.000+0000
{quote} bq. tried to resolve this by extending Zend_Log_Writer_Db to override the _write method, but all of the properties are marked private instead of protected for some reason.
This problem was fixed with ZF-12514.{quote}
Thank you!
I was ultimately able to extend {{Zend_Log_Writer_Db}} in a way that works with the current version. I'm still not sure if this is the best way of handling things, but this is the class I came up with:
Hopefully this is useful to someone else.
Posted by Ralph Schindler (ralph) on 2013-04-05T16:07:14.000+0000
This issue has been closed on Jira and moved to GitHub for issue tracking. To continue following the resolution of this issues, please visit: https://github.com/zendframework/zf1/issues/23