The comments around ThrowErrorData() and how it might apply to soft
errors is slightly confusing. Attached a patch which hopefully
clarifies things.

>From a distance, ThrowErrorData() is somewhat like ReThrowError(), but
it's actually quite different. The former is expecting a free-standing
ErrorData that hasn't been processed at all; while the latter is for an
ERROR specifically, for which errstart() and errfinish() have already
been called.

We also might consider adding some asserts.

Regards,
        Jeff Davis

From 2fc18f71afc89d95eb38fe2d2606b5ff07a8b8f9 Mon Sep 17 00:00:00 2001
From: Jeff Davis <j...@j-davis.com>
Date: Wed, 16 Oct 2024 13:16:02 -0700
Subject: [PATCH v1] Improve ThrowErrorData() comments for use with soft
 errors.

---
 src/backend/utils/error/elog.c | 15 +++++++++------
 src/include/nodes/miscnodes.h  |  7 ++++---
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 987ff98067..8acca3e0a0 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -1881,12 +1881,15 @@ FlushErrorState(void)
 /*
  * ThrowErrorData --- report an error described by an ErrorData structure
  *
- * This is somewhat like ReThrowError, but it allows elevels besides ERROR,
- * and the boolean flags such as output_to_server are computed via the
- * default rules rather than being copied from the given ErrorData.
- * This is primarily used to re-report errors originally reported by
- * background worker processes and then propagated (with or without
- * modification) to the backend responsible for them.
+ * This function should be called on an ErrorData structure that isn't stored
+ * on the errordata stack and hasn't been processed yet. It will call
+ * errstart() and errfinish() as needed, so those should not have already been
+ * called.
+ *
+ * ThrowErrorData() is useful for handling soft errors. It's also useful for
+ * re-reporting errors originally reported by background worker processes and
+ * then propagated (with or without modification) to the backend responsible
+ * for them.
  */
 void
 ThrowErrorData(ErrorData *edata)
diff --git a/src/include/nodes/miscnodes.h b/src/include/nodes/miscnodes.h
index 1612b63acd..f6f2dd4377 100644
--- a/src/include/nodes/miscnodes.h
+++ b/src/include/nodes/miscnodes.h
@@ -36,9 +36,10 @@
  * After calling code that might report an error this way, check
  * error_occurred to see if an error happened.  If so, and if details_wanted
  * is true, error_data has been filled with error details (stored in the
- * callee's memory context!).  FreeErrorData() can be called to release
- * error_data, although that step is typically not necessary if the called
- * code was run in a short-lived context.
+ * callee's memory context!).  The ErrorData can be modified (i.e. downgraded
+ * to a WARNING) and reported with ThrowErrorData().  FreeErrorData() can be
+ * called to release error_data, although that step is typically not necessary
+ * if the called code was run in a short-lived context.
  */
 typedef struct ErrorSaveContext
 {
-- 
2.34.1

Reply via email to