サーバコード内から生成されるエラー、警告、ログメッセージは、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, actual_arg_types)), errhint("Unable to choose a best candidate function. " "You might need to add explicit typecasts.")));
これは、実行時の値をメッセージテキスト内に埋め込むための整形用コードの使用を示します。 また、省略可能な"ヒント"メッセージも提供されています。
ereport
で使用可能な補助ルーチンを以下に示します。
errcode(sqlerrcode)
は、その条件用のSQLSTATEエラー識別コードを指定します。
このルーチンが呼び出されないと、エラー識別子のデフォルトは、エラー深刻度レベルがERROR以上の場合にはERRCODE_INTERNAL_ERRORに、エラー深刻度レベルがWARNINGの場合にはERRCODE_WARNINGに、さもなければ(NOTICE以下)ERRCODE_SUCCESSFUL_COMPLETIONになります。
これらのデフォルトはしばしば便利ですが、errcode()
呼び出しを省略する前に、常に適切かどうかを検討してください。
errmsg(const char *msg, ...)
は、主エラーメッセージテキストを指定し、また、実行時の値をそこに挿入することもできます。
挿入は、sprintf
様式の書式コードで指定されます。
sprintf
で受け付けられる標準の書式コードに加え、%m書式コードを使用して、現在のerrnoの値用のstrerror
で返されるエラーメッセージを挿入することができます。
[1]
%mはerrmsg
のパラメータリスト内に対応する項目を必要としません。
メッセージ文字列は、書式コードの処理を行う前に、地域化のためにgettext
を通ることに注意してください。
errmsg_internal(const char *msg, ...)
は、そのメッセージ文字列は変換されずに国際化用メッセージ辞書が含まれない点を除き、errmsg
と同一です。
これは、おそらく翻訳作業を行う価値がない"発生できなかった"場合用に使用すべきです。
errdetail(const char *msg, ...)
は、省略可能な"詳細"メッセージを提供します。
これは、主メッセージ内に記述するには不適切と考えられる追加情報がある場合に使用されます。
このメッセージ文字列はerrmsg
とまったく同じ方法で処理されます。
errhint(const char *msg, ...)
は、省略可能な"ヒント"メッセージを提供します。
これは、何が悪かったのかについての事実に基づく詳細とは反対で、問題を解決させる方法に関する提言を提供するために使用されます。
このメッセージ文字列はerrmsg
とまったく同じ方法で処理されます。
errcontext(const char *msg, ...)
は通常ereport
メッセージサイトから直接呼び出されません。
エラーが発生したコンテキスト、例えばPL関数の現在位置の情報を提供するためにerror_context_stackコールバック関数内で使用されます。
メッセージ文字列はerrmsg
とまったく同じ方法で処理されます。
他の補助関数とは異なり、1つのereport
呼び出しで何度も呼び出すことができます。
こうして提供される文字列の並びは、改行で区切った形で連結されます。
errposition(int cursorpos)
は、問い合わせ文字列内でエラーが発生した位置をテキストで指定します。
現在、問い合わせ処理の字句解析および構文解析段階でエラーが検出された場合にのみ役に立ちます。
errcode_for_file_access()
は、ファイルアクセス関連のシステムコールでの失敗用のSQLSTATEエラー識別子を適切に選択する、便利な関数です。
保存されたerrnoを使用して、どのエラーコードを生成するかを決定します。
通常、これは主エラーメッセージテキスト内で%mと組み合わせて使用されなければなりません。
errcode_for_socket_access()
は、ソケット関連のシステムコールでの失敗用のSQLSTATEエラー識別子を適切に選択する、便利な関数です。
errhidestmt(bool hide_stmt)
は、postmasterのログ内のメッセージにおけるSTATEMENT:部分を抑制するために呼び出すことができます。
メッセージテキスト内にすでに現在の文が含まれている場合、通常これは適切です。
まだ頻繁に使用されている、古めのelog
関数があります。
以下のelog
呼び出しは、
elog(level, "format string", ...);
以下とまったく同じです。
ereport(level, (errmsg_internal("format string", ...)));
SQLSTATEエラーコードが常にデフォルトになること、メッセージ文字列が変換されないことに注意してください。
したがって、elog
は、内部エラーと低レベルなデバッグ用ログにのみ使用すべきです。
一般ユーザを対象とする任意のメッセージはereport
を使用すべきです。
それでもなお、システム内の"発生できなかった"内部エラーの検査にelog
がまだ多く使用されています。
これは、こうした単純な表記のメッセージに適しています。
項46.3に推奨するエラーメッセージの作成についての提言を示します。
[1] | つまり、 |