Add a new ereport auxiliary function errdetail_log(), which works the same as
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 24 Mar 2008 18:08:47 +0000 (18:08 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 24 Mar 2008 18:08:47 +0000 (18:08 +0000)
errdetail except the string goes only to the server log, replacing the normal
errdetail there.  This provides a reasonably clean way of dealing with error
details that are too security-sensitive or too bulky to send to the client.

This commit just adds the infrastructure --- actual uses to follow.

doc/src/sgml/sources.sgml
src/backend/nls.mk
src/backend/port/ipc_test.c
src/backend/utils/error/elog.c
src/include/utils/elog.h

index a0e423d02f15759a51b747fa9b220f751b14c416..87c3c5bddbff51eea828ca0a00b145b30981500a 100644 (file)
@@ -158,6 +158,17 @@ ereport(ERROR,
      <function>errmsg</>.
     </para>
    </listitem>
+   <listitem>
+    <para>
+     <function>errdetail_log(const char *msg, ...)</function> is the same as
+     <function>errdetail</> except that this string goes only to the server
+     log, never to the client.  If both <function>errdetail</> and
+     <function>errdetail_log</> are used then one string goes to the client
+     and the other to the log.  This is useful for error details that are
+     too security-sensitive or too bulky to include in the report
+     sent to the client.
+    </para>
+   </listitem>
    <listitem>
     <para>
      <function>errhint(const char *msg, ...)</function> supplies an optional
index 1cd5694044f864b3213980342c30dd0922f0b61d..ec9c3064c601475a34bc4137e38ecac6eb372b52 100644 (file)
@@ -4,7 +4,7 @@ AVAIL_LANGUAGES := af cs de es fr hr hu it ko nb nl pt_BR ro ru sk sl sv tr zh_C
 GETTEXT_FILES  := + gettext-files
 # you can add "elog:2" and "errmsg_internal" to this list if you want to
 # include internal messages in the translation list.
-GETTEXT_TRIGGERS:= _ errmsg errdetail errhint errcontext write_stderr yyerror
+GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext write_stderr yyerror
 
 gettext-files: distprep
        find $(srcdir)/ $(srcdir)/../port/ -name '*.c' -print >$@
index d7320195a5f01ce6e1e24d387196e564b3682b61..23b9177b187f0d48e51c2da536990e29525e4b16 100644 (file)
@@ -185,6 +185,13 @@ errdetail(const char *fmt,...)
        return 0;                                       /* return value does not matter */
 }
 
+int
+errdetail_log(const char *fmt,...)
+{
+       fprintf(stderr, "DETAIL: %s\n", fmt);
+       return 0;                                       /* return value does not matter */
+}
+
 int
 errhint(const char *fmt,...)
 {
index 1d2f522cca3715ef6933e3ab0227bcc476127954..3ff91811a35b9e56b6ae00214e0b80c693eba3b9 100644 (file)
@@ -382,6 +382,8 @@ errfinish(int dummy,...)
                pfree(edata->message);
        if (edata->detail)
                pfree(edata->detail);
+       if (edata->detail_log)
+               pfree(edata->detail_log);
        if (edata->hint)
                pfree(edata->hint);
        if (edata->context)
@@ -700,6 +702,27 @@ errdetail(const char *fmt,...)
 }
 
 
+/*
+ * errdetail_log --- add a detail_log error message text to the current error
+ */
+int
+errdetail_log(const char *fmt,...)
+{
+       ErrorData  *edata = &errordata[errordata_stack_depth];
+       MemoryContext oldcontext;
+
+       recursion_depth++;
+       CHECK_STACK_DEPTH();
+       oldcontext = MemoryContextSwitchTo(ErrorContext);
+
+       EVALUATE_MESSAGE(detail_log, false);
+
+       MemoryContextSwitchTo(oldcontext);
+       recursion_depth--;
+       return 0;                                       /* return value does not matter */
+}
+
+
 /*
  * errhint --- add a hint error message text to the current error
  */
@@ -1010,6 +1033,8 @@ CopyErrorData(void)
                newedata->message = pstrdup(newedata->message);
        if (newedata->detail)
                newedata->detail = pstrdup(newedata->detail);
+       if (newedata->detail_log)
+               newedata->detail_log = pstrdup(newedata->detail_log);
        if (newedata->hint)
                newedata->hint = pstrdup(newedata->hint);
        if (newedata->context)
@@ -1033,6 +1058,8 @@ FreeErrorData(ErrorData *edata)
                pfree(edata->message);
        if (edata->detail)
                pfree(edata->detail);
+       if (edata->detail_log)
+               pfree(edata->detail_log);
        if (edata->hint)
                pfree(edata->hint);
        if (edata->context)
@@ -1103,6 +1130,8 @@ ReThrowError(ErrorData *edata)
                newedata->message = pstrdup(newedata->message);
        if (newedata->detail)
                newedata->detail = pstrdup(newedata->detail);
+       if (newedata->detail_log)
+               newedata->detail_log = pstrdup(newedata->detail_log);
        if (newedata->hint)
                newedata->hint = pstrdup(newedata->hint);
        if (newedata->context)
@@ -1790,8 +1819,11 @@ write_csvlog(ErrorData *edata)
        appendCSVLiteral(&buf, edata->message);
        appendStringInfoCharMacro(&buf, ',');
 
-       /* errdetail */
-       appendCSVLiteral(&buf, edata->detail);
+       /* errdetail or errdetail_log */
+       if (edata->detail_log)
+               appendCSVLiteral(&buf, edata->detail_log);
+       else
+               appendCSVLiteral(&buf, edata->detail);
        appendStringInfoCharMacro(&buf, ',');
 
        /* errhint */
@@ -1907,7 +1939,14 @@ send_message_to_server_log(ErrorData *edata)
 
        if (Log_error_verbosity >= PGERROR_DEFAULT)
        {
-               if (edata->detail)
+               if (edata->detail_log)
+               {
+                       log_line_prefix(&buf);
+                       appendStringInfoString(&buf, _("DETAIL:  "));
+                       append_with_tabs(&buf, edata->detail_log);
+                       appendStringInfoChar(&buf, '\n');
+               }
+               else if (edata->detail)
                {
                        log_line_prefix(&buf);
                        appendStringInfoString(&buf, _("DETAIL:  "));
@@ -2157,6 +2196,8 @@ send_message_to_frontend(ErrorData *edata)
                        pq_sendstring(&msgbuf, edata->detail);
                }
 
+               /* detail_log is intentionally not used here */
+
                if (edata->hint)
                {
                        pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);
index 0872032d9b54fad82726074025769943bb214987..c12fdde39faafed4ffa280a2662411cfc383556b 100644 (file)
@@ -125,6 +125,12 @@ errdetail(const char *fmt,...)
    the supplied arguments. */
 __attribute__((format(printf, 1, 2)));
 
+extern int
+errdetail_log(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+   the supplied arguments. */
+__attribute__((format(printf, 1, 2)));
+
 extern int
 errhint(const char *fmt,...)
 /* This extension allows gcc to check the format string for consistency with
@@ -258,6 +264,7 @@ typedef struct ErrorData
        int                     sqlerrcode;             /* encoded ERRSTATE */
        char       *message;            /* primary error message */
        char       *detail;                     /* detail error message */
+       char       *detail_log;         /* detail error message for server log only */
        char       *hint;                       /* hint message */
        char       *context;            /* context message */
        int                     cursorpos;              /* cursor index into query string */