CakePHPでDBのExceptionが起こった時にどういうSQLを投げたためかをログに吐く
何か変なqueryをMySQLに投げてしまって
2012-05-26 18:23:21 Error: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`test`.`user_logs`, CONSTRAINT `user_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))
みたいな感じでPDOExceptionが発生した場合に、どんなSQLを実行したのかがわからなくて困ったので調べた。
debugモードであればqueriesLogに保存されてそれを覗けばわかるのだけど、本番だとqueriesLogには保存されないのでそれだとダメ。
ググっても「queriesLog覗けばいいよ」とか「getLog()実行すればいい」的なのばかり出て来てなかなか欲しい情報にたどり着けず。
# というか、結局エラーが出た時にSQLが調べられればいいのでdebugモードのときみたいに常にある必要はない
で、ソース見たらあった。
<?php // https://github.com/cakephp/cakephp/blob/master/lib/Cake/Model/Datasource/DboSource.php#L449 } catch (PDOException $e) { if (isset($query->queryString)) { $e->queryString = $query->queryString; } else { $e->queryString = $sql; } throw $e; }
PDEOExceptionが起こった時に$eのqueryStringに突っ込んでる。
なのでexceptionで捕まえた時にコレをそのままログに吐けばいい。
ってことで、AppModelの中でException捕まえて、その中で
<?php CakeLog::write('error', $e->getMessage()); CakeLog::write('error', $e->queryString);
みたいな感じでログに吐くことにした。
結果、
Error: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`test`.`user_logs`, CONSTRAINT `user_logs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) Error: INSERT INTO `test`.`user_logs` (`is_error`, `modified`, `created`) VALUES ('1', '2012-05-26 18:23:20', '2012-05-26 18:23:20')
こんな感じでログが吐かれる