Commit 05fc744b authored by Tom Lane's avatar Tom Lane

Add a new ereport auxiliary function errdetail_log(), which works the same as

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.
parent 7feabcbf
<!-- $PostgreSQL: pgsql/doc/src/sgml/sources.sgml,v 2.29 2007/11/07 13:12:21 petere Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/sources.sgml,v 2.30 2008/03/24 18:08:47 tgl Exp $ -->
<chapter id="source"> <chapter id="source">
<title>PostgreSQL Coding Conventions</title> <title>PostgreSQL Coding Conventions</title>
...@@ -158,6 +158,17 @@ ereport(ERROR, ...@@ -158,6 +158,17 @@ ereport(ERROR,
<function>errmsg</>. <function>errmsg</>.
</para> </para>
</listitem> </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> <listitem>
<para> <para>
<function>errhint(const char *msg, ...)</function> supplies an optional <function>errhint(const char *msg, ...)</function> supplies an optional
......
# $PostgreSQL: pgsql/src/backend/nls.mk,v 1.21 2008/01/30 11:05:37 petere Exp $ # $PostgreSQL: pgsql/src/backend/nls.mk,v 1.22 2008/03/24 18:08:47 tgl Exp $
CATALOG_NAME := postgres CATALOG_NAME := postgres
AVAIL_LANGUAGES := af cs de es fr hr hu it ko nb nl pt_BR ro ru sk sl sv tr zh_CN zh_TW AVAIL_LANGUAGES := af cs de es fr hr hu it ko nb nl pt_BR ro ru sk sl sv tr zh_CN zh_TW
GETTEXT_FILES := + gettext-files GETTEXT_FILES := + gettext-files
# you can add "elog:2" and "errmsg_internal" to this list if you want to # you can add "elog:2" and "errmsg_internal" to this list if you want to
# include internal messages in the translation list. # 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 gettext-files: distprep
find $(srcdir)/ $(srcdir)/../port/ -name '*.c' -print >$@ find $(srcdir)/ $(srcdir)/../port/ -name '*.c' -print >$@
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/port/ipc_test.c,v 1.23 2008/01/01 19:45:51 momjian Exp $ * $PostgreSQL: pgsql/src/backend/port/ipc_test.c,v 1.24 2008/03/24 18:08:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -185,6 +185,13 @@ errdetail(const char *fmt,...) ...@@ -185,6 +185,13 @@ errdetail(const char *fmt,...)
return 0; /* return value does not matter */ 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 int
errhint(const char *fmt,...) errhint(const char *fmt,...)
{ {
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.202 2008/03/10 12:55:13 mha Exp $ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.203 2008/03/24 18:08:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -382,6 +382,8 @@ errfinish(int dummy,...) ...@@ -382,6 +382,8 @@ errfinish(int dummy,...)
pfree(edata->message); pfree(edata->message);
if (edata->detail) if (edata->detail)
pfree(edata->detail); pfree(edata->detail);
if (edata->detail_log)
pfree(edata->detail_log);
if (edata->hint) if (edata->hint)
pfree(edata->hint); pfree(edata->hint);
if (edata->context) if (edata->context)
...@@ -700,6 +702,27 @@ errdetail(const char *fmt,...) ...@@ -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 * errhint --- add a hint error message text to the current error
*/ */
...@@ -1010,6 +1033,8 @@ CopyErrorData(void) ...@@ -1010,6 +1033,8 @@ CopyErrorData(void)
newedata->message = pstrdup(newedata->message); newedata->message = pstrdup(newedata->message);
if (newedata->detail) if (newedata->detail)
newedata->detail = pstrdup(newedata->detail); newedata->detail = pstrdup(newedata->detail);
if (newedata->detail_log)
newedata->detail_log = pstrdup(newedata->detail_log);
if (newedata->hint) if (newedata->hint)
newedata->hint = pstrdup(newedata->hint); newedata->hint = pstrdup(newedata->hint);
if (newedata->context) if (newedata->context)
...@@ -1033,6 +1058,8 @@ FreeErrorData(ErrorData *edata) ...@@ -1033,6 +1058,8 @@ FreeErrorData(ErrorData *edata)
pfree(edata->message); pfree(edata->message);
if (edata->detail) if (edata->detail)
pfree(edata->detail); pfree(edata->detail);
if (edata->detail_log)
pfree(edata->detail_log);
if (edata->hint) if (edata->hint)
pfree(edata->hint); pfree(edata->hint);
if (edata->context) if (edata->context)
...@@ -1103,6 +1130,8 @@ ReThrowError(ErrorData *edata) ...@@ -1103,6 +1130,8 @@ ReThrowError(ErrorData *edata)
newedata->message = pstrdup(newedata->message); newedata->message = pstrdup(newedata->message);
if (newedata->detail) if (newedata->detail)
newedata->detail = pstrdup(newedata->detail); newedata->detail = pstrdup(newedata->detail);
if (newedata->detail_log)
newedata->detail_log = pstrdup(newedata->detail_log);
if (newedata->hint) if (newedata->hint)
newedata->hint = pstrdup(newedata->hint); newedata->hint = pstrdup(newedata->hint);
if (newedata->context) if (newedata->context)
...@@ -1790,7 +1819,10 @@ write_csvlog(ErrorData *edata) ...@@ -1790,7 +1819,10 @@ write_csvlog(ErrorData *edata)
appendCSVLiteral(&buf, edata->message); appendCSVLiteral(&buf, edata->message);
appendStringInfoCharMacro(&buf, ','); appendStringInfoCharMacro(&buf, ',');
/* errdetail */ /* errdetail or errdetail_log */
if (edata->detail_log)
appendCSVLiteral(&buf, edata->detail_log);
else
appendCSVLiteral(&buf, edata->detail); appendCSVLiteral(&buf, edata->detail);
appendStringInfoCharMacro(&buf, ','); appendStringInfoCharMacro(&buf, ',');
...@@ -1907,7 +1939,14 @@ send_message_to_server_log(ErrorData *edata) ...@@ -1907,7 +1939,14 @@ send_message_to_server_log(ErrorData *edata)
if (Log_error_verbosity >= PGERROR_DEFAULT) 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); log_line_prefix(&buf);
appendStringInfoString(&buf, _("DETAIL: ")); appendStringInfoString(&buf, _("DETAIL: "));
...@@ -2157,6 +2196,8 @@ send_message_to_frontend(ErrorData *edata) ...@@ -2157,6 +2196,8 @@ send_message_to_frontend(ErrorData *edata)
pq_sendstring(&msgbuf, edata->detail); pq_sendstring(&msgbuf, edata->detail);
} }
/* detail_log is intentionally not used here */
if (edata->hint) if (edata->hint)
{ {
pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT); pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.91 2008/03/10 12:55:13 mha Exp $ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.92 2008/03/24 18:08:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -125,6 +125,12 @@ errdetail(const char *fmt,...) ...@@ -125,6 +125,12 @@ errdetail(const char *fmt,...)
the supplied arguments. */ the supplied arguments. */
__attribute__((format(printf, 1, 2))); __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 extern int
errhint(const char *fmt,...) errhint(const char *fmt,...)
/* This extension allows gcc to check the format string for consistency with /* This extension allows gcc to check the format string for consistency with
...@@ -258,6 +264,7 @@ typedef struct ErrorData ...@@ -258,6 +264,7 @@ typedef struct ErrorData
int sqlerrcode; /* encoded ERRSTATE */ int sqlerrcode; /* encoded ERRSTATE */
char *message; /* primary error message */ char *message; /* primary error message */
char *detail; /* detail error message */ char *detail; /* detail error message */
char *detail_log; /* detail error message for server log only */
char *hint; /* hint message */ char *hint; /* hint message */
char *context; /* context message */ char *context; /* context message */
int cursorpos; /* cursor index into query string */ int cursorpos; /* cursor index into query string */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment