Re: try/catch macros for Postgres backend - Mailing list pgsql-hackers

From Tom Lane
Subject Re: try/catch macros for Postgres backend
Date
Msg-id 13617.1091109534@sss.pgh.pa.us
Whole thread Raw
In response to Re: try/catch macros for Postgres backend  ("Jeroen T. Vermeulen" <jtv@xs4all.nl>)
Responses Re: try/catch macros for Postgres backend  ("Jeroen T. Vermeulen" <jtv@xs4all.nl>)
List pgsql-hackers
"Jeroen T. Vermeulen" <jtv@xs4all.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_indentwill indent the construct nicely.)  The error recovery code* can optionally do PG_RE_THROW() to propagate the
sameerror 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*
sectionsimple 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


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: try/catch macros for Postgres backend
Next
From: "Jeroen T. Vermeulen"
Date:
Subject: Re: try/catch macros for Postgres backend