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ファイル
image

原因は単純なコードミス
何よりダメなのは$sth->prepareが失敗している可能性があるにもかかわらず、$dbh->executeして、さらにはforループの条件式に$sth->rowsを参照している事。
しかし、$sth->rowsは基本的に参照できないときには-1を返すので、固定SQLなどの絶対失敗しないSQLしかテストしていない場合、このエラーに気づくことはありません。

気をつけましょう。そしてみんなごめんなさい。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.