From 65127dced44b737179af53f2d3aca6b1b9993fa2 Mon Sep 17 00:00:00 2001
From: Craig Ringer <craig.ringer@2ndquadrant.com>
Date: Thu, 3 Sep 2020 12:53:44 +0800
Subject: [PATCH 1/9] Add some documentation on error context callback usage

---
 src/include/utils/elog.h | 55 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 1e09ee0541..18276e1e93 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -221,7 +221,60 @@ extern void pre_format_elog_string(int errnumber, const char *domain);
 extern char *format_elog_string(const char *fmt,...) pg_attribute_printf(1, 2);
 
 
-/* Support for attaching context information to error reports */
+/*
+ * Support for attaching context information to error reports.
+ *
+ * Functions may set append their own ErrorContextCallback to the
+ * error_context_stack chain to have callbacks invoked during ereport() or
+ * elog() processing, optionally with a pointer to local state.
+ *
+ * The callback typically calls errcontext() one or more times to append
+ * to the CONTEXT field of the error report.
+ *
+ * Error context callbacks may be omitted when Pg can show that it will not
+ * emit the error message, so it is not safe for an error context callback to
+ * have side-effects.
+ *
+ * Any memory allocated must be in the CurrentMemoryContext which is set to
+ * ErrorContext before the callback is invoked.
+ *
+ * The typical usage pattern is:
+ *
+ *     struct MyFuncErrctxArg {
+ *        // track your state here for error reporting
+ *        int some_info_here;
+ *     };
+ *
+ *     static void
+ *     my_func_errctx_callback(void *arg)
+ *     {
+ *         struct MyFuncErrctxArg *ctxarg = arg;
+ *         errcontext("in my_func() with some_info=%d",
+ *             ctxarg->some_info_here;
+ *     }
+ *
+ *     void
+ *     my_func(void)
+ *     {
+ *         ErrorContextCallback errctx;
+ *         struct MyFuncErrctxArg ctxarg;
+ *
+ *         errctx.callback = my_func_errctx_callback;
+ *         errctx.arg = &ctxarg;
+ *         errctx.previous = error_context_stack;
+ *         error_context_stack = &errctx;
+ *
+ *         // do your normal work here but (important) do NOT return without
+ *         // popping the error context stack:
+ *
+ *         if (error_context_stack == &errctx)
+ *             error_context_stack = error_context_stack->previous;
+ *     }
+ *
+ * It's a bit verbose, but extremely valuable for adding extra diagnostic
+ * information to errors at runtime.
+ *------------
+ */
 
 typedef struct ErrorContextCallback
 {
-- 
2.26.2

