Perlではよく例外処理の代わりにeval を利用していると思います。
私はいつもこんなコードを書いてCGIで実行していました。
※ひとまずコードへのツッコミは無しで^^
eval {
$sth = $dbh->prepare(
"ほにゃららSQL"
);
$sth->execute;
for(my $i=0; $i<$sth->rows; $i++){
my @row = $sth->fetchrow_array;
$data[$i]{id} = $row[0];
$data[$i]{name} = $row[1];
}
$sth->finish;
};
このコードはSQLがエラー無く通った場合、何事もなく処理されます。
しかし、万が一、生成されたSQL文の文法エラーやMySQLサーバーの異常などで $dbh->prepare()
が失敗した場合、どんなことが起きるかというと・・・
eval関数によってエラーが無視され、メモリを圧迫、放っておくとHTTPDのエラーログが膨大なサイズに膨れ上がって、しまいにはサーバーがダウンします。
こんなくだらないエラーログだけで28GBまで膨れ上がったerror.logファイル
原因は単純なコードミス
何よりダメなのは$sth->prepare
が失敗している可能性があるにもかかわらず、$dbh->execute
して、さらにはforループの条件式に$sth->rows
を参照している事。
しかし、$sth->rows
は基本的に参照できないときには-1
を返すので、固定SQLなどの絶対失敗しないSQLしかテストしていない場合、このエラーに気づくことはありません。
気をつけましょう。そしてみんなごめんなさい。