Re: try/catch macros for Postgres backend

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Jeroen T(dot) Vermeulen" <jtv(at)xs4all(dot)nl>
Cc: Alvaro Herrera Munoz <alvherre(at)dcc(dot)uchile(dot)cl>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: try/catch macros for Postgres backend
Date: 2004-07-29 13:58:54
Message-ID: 13617.1091109534@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

"Jeroen T. Vermeulen" <jtv(at)xs4all(dot)nl> writes:
> ...Or I could try. Yes, the "finally" block is executed after executing
> the "catch" block if an exception was caught, or when leaving the "try"
> block if there wasn't. That includes both normal completion and uncaught
> exceptions.

Right. The last bit (FINALLY executes whether or not a CATCH block
re-throws) seemed too messy to handle in my little macros, so I'm
planning on leaving it out. But I'm open to the idea if anyone has
a clever implementation thought.

What I have turning over at the moment is

/*----------
* 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;

It's passing regression tests but I have some loose ends to fix before
committing.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Korea PostgreSQL Users' Group 2004-07-29 14:06:17 Re: win32 crash in initdb - it has still problems.
Previous Message Tom Lane 2004-07-29 13:50:17 Re: try/catch macros for Postgres backend