無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

49.2. サーバ内部からのエラーの報告

サーバコード内から生成されるエラー、警告、ログメッセージは、 ereport もしくはこれに似た古い elog を使用して作成してください。 この関数の使用はいくつか説明が必要なほど複雑です。

すべてのメッセージには、深刻度レベル( DEBUG から PANIC までの範囲)と主メッセージテキストという、2つの必須要素があります。 さらに、省略可能な要素があります。 その中で最もよく使用されるのは、SQL仕様のSQLSTATE規則に従うエラー識別コードです。 ereport 自身はシェル関数で、主に、メッセージ生成をCソースコード内の関数呼び出しのように行わせる、構文の便宜上存在します。 ereport で直接受け付けられる唯一のパラメータは深刻度レベルです。 主メッセージテキストと任意の省略可能なメッセージ要素は、 ereport 呼び出し内で errmsg などの補助関数を呼び出すことで生成されます。

典型的な ereport の呼び出しは以下のようなものです。

ereport(ERROR,
        (errcode(ERRCODE_DIVISION_BY_ZERO),
         errmsg("division by zero")));

これはエラー深刻度レベル ERROR (普通のエラー)を指定します。 errcode 呼び出しは、 src/include/utils/errcodes.h で定義されたマクロを使用してSQLSTATEエラーコードを指定します。 errmsg 呼び出しは主メッセージテキストを提供します。 補助関数呼び出しを囲む余計な括弧群に注意してください。 これらはいらいらさせられますが、構文上必要です。

以下に、より複雑な例を示します。

ereport(ERROR,
        (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
         errmsg("function %s is not unique",
                func_signature_string(funcname, nargs,
                                      NIL, actual_arg_types)),
         errhint("Unable to choose a best candidate function. "
                 "You might need to add explicit typecasts.")));

これは、実行時の値をメッセージテキスト内に埋め込むための整形用コードの使用を示します。 また、省略可能な "ヒント" メッセージも提供されています。

ereport で使用可能な補助ルーチンを以下に示します。

注意: ereport 呼び出しにおいて、最大限でも errtable errtablecol errtableconstraint errdatatype 、または errdomainconstraint のうちの一つの関数が使用されなければなりません。 これらの関数は、アプリケーションが自動エラー対応であって欲しいと期待するエラーレポートにおいて使用されるべきです。 PostgreSQL 9.3の時点で、この機能を完璧に保証する範囲はSQLSTATEクラス23(整合性制約違反)のみですが、将来的には十中八九拡張されそうです。

まだ頻繁に使用されている、古めの elog 関数があります。 以下の elog 呼び出しは、

elog(level, "format string", ...);

以下とまったく同じです。

ereport(level, (errmsg_internal("format string", ...)));

SQLSTATEエラーコードが常にデフォルトになること、メッセージ文字列が変換されないことに注意してください。 したがって、 elog は、内部エラーと低レベルなデバッグ用ログにのみ使用すべきです。 一般ユーザを対象とする任意のメッセージは ereport を使用すべきです。 それでもなお、システム内の "発生できなかった" 内部エラーの検査に elog がまだ多く使用されています。 これは、こうした単純な表記のメッセージに適しています。

項49.3 に推奨するエラーメッセージの作成についての提言を示します。

注意

[1]

つまり、 ereport 呼び出しに達した時点の値です。 補助報告ルーチン内で errno を変更しても効果はありません。 errmsg 内で strerror(errno) を明示的に記述したとしても正確なものにはなりません。 したがって、このようにはしないでください。


powered by SEO.CUG.NET