Kawa.netxp [Perl] KCatch.pm/CGI エラーメッセージをブラウザに表示

持ってるだけで安心する

KCatch.pm は Perl CGI で発生する Internal Server Error を補足して、 エラー内容を HTML としてブラウザ画面に表示してくれるモジュールです。
エラーの発生した行番号なども表示されるので、サーバ上での開発に最適です。

CodeRepos にソースを移動しました!(2007/12/23)

KCatch.pmでは CGI スクリプト実行中のエラーだけでなく HTTPヘッダを出力する前に発生したエラーについても捕捉されます。 実行前のコンパイル時のエラー(Perl文法エラー)や、 use/require しているモジュール/ライブラリが存在しない場合などの Internal Server Errorをも回避できます。 CGI開発作業時には、このメリットは大きいです。

KCatch.pm のもっとも簡単な使い方

ここでは、もっとも簡単な KCatch.pm の導入方法を示します。

まず、ダウンロードしたアーカイブから KCatch.pm ファイルを取り出し、 ウェブサーバの CGI ファイルと同じディレクトリ(または @INC なディレクトリ)に アップロードしてください。
KCatch.pm のパーミションは rw-r--r-- (644) とします。

CGI プログラムの先頭 (#!/usr/bin/perl の後か、use strict; の後) に、

use KCatch;

の1行を追加するだけです。以上で、完了です。
外部 Perl モジュールの呼び出しエラーや、die・warn のメッセージなど、 CGI 実行処理中に発生する多くのエラーを捕捉できます。

KCatch.pm のより適切な使い方【オススメ】

CGI プログラム本体内の Perl の構文エラーなどは、 use KCatch 行が実行される前にエラー終了してしまうため、 KCatch では捕捉できません。
そこで、以下の手順を使えば、ほぼ全ての CGI エラー確実に捕捉することができます。

仮に、以下のような CGI プログラム hello.cgi に KCatch.pm を導入する場合は、

#!/usr/bin/perl

use strict;
print "Content-Type: text/html\n\n";
print "Hello, World!!\n";
print scalar localtime(), "\n";

この hello.cgi の本文は書き換えずに、 ファイル名をhello-main.plと変更してください。
hello-main.plの末尾に以下の1行を追加します。(オマジナイ)

;1;

次に、hello.cgiというファイル名で

#!/usr/bin/perl

use strict;
use KCatch;
require "hello-main.pl";

だけの内容にします。 hello.cgi のパーミションは通常通り rwxr-xr-x (755) とします。
これだけの手順で、hello-main.pl中で発生したエラーは捕捉され、 ブラウザ画面にエラー内容が赤文字で表示されます。

KCatch.pm の主なオプション

KCatch.pm は、use 行にていくつかのオプションを指定できます。
代表的なオプションを紹介します。

source - ソース表示オプション

use KCatch qw( source );

warn や die の発生した行のソースコードも表示します。
開発時に便利ですが、一般公開後に何らかのエラーが発生した場合、 一般ユーザにもコードが見えてしまうため、 セキュリティ上の問題に生じる可能性もあります。
デバッグ完了後・一般公開前にはこのオプションは外しましょう。

stderr - エラー内容の STDERR への追加出力

use KCatch qw( stderr );

エラー内容をブラウザ画面だけでなく、 標準エラー出力 STDERR にも吐き出します。
Apache のエラーログに書き込まれるため、 エラー内容の確認に便利です。

Jcode=sjis - 日本語エラーメッセージの出力

jcode=sjis または Jcode=sjis オプションでは、 エラー文字列中の日本語文字コードを Shift_JIS に指定できます。 『CGI の内部処理コードは EUC-JP だけれども、 PC 用に出力コードは Shift_JIS にしている環境』などに有用です。

use Jcode;
use KCatch qw( Jcode=sjis );

のように Jcode=sjis オプションを利用する場合は、 予め Jcode.pm が必要です。
(内部コードとしてUTF8も利用可能です)

require "jcode.pl";
use KCatch qw( jcode=sjis );

のように jcode=sjis オプションを利用する場合は、 予め jcode.pl が必要です。
(内部コードとしてUTF8は利用できません)

execdata - あまり推奨されないオプション

この他に、execdata オプション(別名:救世主オプション)もありますが、 この execdata オプションを利用するよりも、 このページで紹介している hello.cgi〜hello-main.pl のように ソースファイルを分離する手順の方がより確実にエラーを補足できます。
そのため、現在は execdata オプションの利用よりも、 ソース分離形式をお勧めします。

頻出エラーメッセージ

Perl CGI 開発時のありがちなエラーメッセージを紹介します。

Global symbol "$xxxx" requires explicit package name 

use strict 環境下では、全ての変数は my や local で 使用する前に宣言する必要があります。
このエラーが出る場合、宣言し忘れている変数があるか、 または、スクリプト中の変数名の誤字が考えられます。

Missing right bracket 

このエラーが出る場合、開きカッコ“{”が閉じていません。
ループや条件分岐 if 文の入れ子構造で、 閉じ忘れたカッコ“}”があるようです。

unmatched () in regexp 

正規表現中の“(”が閉じていません。
“(”の数だけ“)”を閉じているか確認したり、 s///; m//; の要素数が正しいかを確認してください。
“(”自体の文字を検索したい場合は、“\(”や“\Q(\E”とエスケープします。

Can't coerce array into hash 

リスト配列(ARRAY)へのリファレンスを ハッシュ(HASH)として利用しようとした場合に発生します。
$list->[0] とすべき箇所を $list->{0} のように記述していいないでしょうか?

Can't call method "xxxx" without a package or object reference
Can't call method "xxxx" on an undefined value

このエラーが出る場合、 未定義値や正しくクラスと関連付けられていない(未bless)変数に対して メソッド呼び出しを実行した場合に発生します。
具体的には、new() コンストラクタの処理でエラーが発生したのに、 エラー判定をせずに続けてメソッドを呼び出した場合などです。

xxxx.pl did not return a true value

use/require される側のPerlモジュール/ライブラリでは、 最後の行は必ず真を返す必要があります。 このエラーメッセージが表示された場合は、 該当ファイルの最後の行にオマジナイの1行

;1;

を追加してください。

関連情報

KCatch.pmを紹介してくれているページ:

なお、KCatch.pm と似た機能を持つ Perl モジュールとして、 CGI::Carp があります。 こちらは CPAN からインストールできます。
ブラウザへのエラー内容表示は CGI::Carp の fatalsToBrowser オプションが近い処理になりますが、 KCatch.pm の方が捕捉〜表示が確実な気がします。
逆に、ブラウザへのエラー表示以外の機能については CGI::Carp の方が高機能な面もあります。

その他のモジュール・ライブラリ

コメントはこちらへ by AjaxCom

このページへのトラックバック by AjaxTB

トラックバックURL:http://www.kawa.net/service/tb/ajaxtb.cgi/works/perl/catch/news.html

Kawa.netxp © Copyright 2000-2004 Yusuke Kawasaki