aboutsummaryrefslogtreecommitdiff
path: root/src/include/utils/elog.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-07-31 00:45:57 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-07-31 00:45:57 +0000
commita393fbf93763709f90ba1f968e50a35bd4cabcfb (patch)
tree955d74e7181214688b575f31c243005fe470dfe1 /src/include/utils/elog.h
parent94f8f63fdbcf61a56a23b8052d68fd78bec86a3b (diff)
downloadpostgresql-a393fbf93763709f90ba1f968e50a35bd4cabcfb.tar.gz
postgresql-a393fbf93763709f90ba1f968e50a35bd4cabcfb.zip
Restructure error handling as recently discussed. It is now really
possible to trap an error inside a function rather than letting it propagate out to PostgresMain. You still have to use AbortCurrentTransaction to clean up, but at least the error handling itself will cooperate.
Diffstat (limited to 'src/include/utils/elog.h')
-rw-r--r--src/include/utils/elog.h91
1 files changed, 90 insertions, 1 deletions
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 99e2932f3a8..e9f2b0e879f 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -7,13 +7,15 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.70 2004/07/06 19:51:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.71 2004/07/31 00:45:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef ELOG_H
#define ELOG_H
+#include <setjmp.h>
+
/* Error level codes */
#define DEBUG5 10 /* Debugging messages, in categories of
* decreasing detail. */
@@ -168,6 +170,93 @@ typedef struct ErrorContextCallback
extern DLLIMPORT ErrorContextCallback *error_context_stack;
+/*----------
+ * API for catching ereport(ERROR) exits. Use these macros like so:
+ *
+ * PG_TRY();
+ * {
+ * ... code that might throw ereport(ERROR) ...
+ * }
+ * PG_CATCH();
+ * {
+ * ... error recovery code ...
+ * }
+ * PG_END_TRY();
+ *
+ * (The braces are not actually necessary, but are recommended so that
+ * pg_indent will indent the construct nicely.) The error recovery code
+ * can optionally do PG_RE_THROW() to propagate the same error outwards.
+ *
+ * Note: while the system will correctly propagate any new ereport(ERROR)
+ * occurring in the recovery section, there is a small limit on the number
+ * of levels this will work for. It's best to keep the error recovery
+ * section simple enough that it can't generate any new errors, at least
+ * not before popping the error stack.
+ *----------
+ */
+#define PG_TRY() \
+ do { \
+ sigjmp_buf *save_exception_stack = PG_exception_stack; \
+ ErrorContextCallback *save_context_stack = error_context_stack; \
+ sigjmp_buf local_sigjmp_buf; \
+ if (sigsetjmp(local_sigjmp_buf, 1) == 0) \
+ { \
+ PG_exception_stack = &local_sigjmp_buf
+
+#define PG_CATCH() \
+ } \
+ else \
+ { \
+ PG_exception_stack = save_exception_stack; \
+ error_context_stack = save_context_stack
+
+#define PG_END_TRY() \
+ } \
+ PG_exception_stack = save_exception_stack; \
+ error_context_stack = save_context_stack; \
+ } while (0)
+
+#define PG_RE_THROW() \
+ siglongjmp(*PG_exception_stack, 1)
+
+extern DLLIMPORT sigjmp_buf *PG_exception_stack;
+
+
+/* Stuff that error handlers might want to use */
+
+/*
+ * ErrorData holds the data accumulated during any one ereport() cycle.
+ * Any non-NULL pointers must point to palloc'd data.
+ * (The const pointers are an exception; we assume they point at non-freeable
+ * constant strings.)
+ */
+typedef struct ErrorData
+{
+ int elevel; /* error level */
+ bool output_to_server; /* will report to server log? */
+ bool output_to_client; /* will report to client? */
+ bool show_funcname; /* true to force funcname inclusion */
+ const char *filename; /* __FILE__ of ereport() call */
+ int lineno; /* __LINE__ of ereport() call */
+ const char *funcname; /* __func__ of ereport() call */
+ int sqlerrcode; /* encoded ERRSTATE */
+ char *message; /* primary error message */
+ char *detail; /* detail error message */
+ char *hint; /* hint message */
+ char *context; /* context message */
+ int cursorpos; /* cursor index into query string */
+ int internalpos; /* cursor index into internalquery */
+ char *internalquery; /* text of internally-generated query */
+ int saved_errno; /* errno at entry */
+} ErrorData;
+
+extern void EmitErrorReport(void);
+extern ErrorData *CopyErrorData(void);
+extern void FreeErrorData(ErrorData *edata);
+extern void FlushErrorState(void);
+extern void ReThrowError(ErrorData *edata);
+
+
/* GUC-configurable parameters */
typedef enum