On 12/13/18 7:26 AM, Kyotaro HORIGUCHI wrote:
> At Thu, 13 Dec 2018 11:33:39 +0100, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote in
<c170919d-c78b-3dac-5ff6-9bd12f7a38bc@2ndquadrant.com>
>>
>> I've played with a way to express this more compactly:
>>
>> PG_TRY();
>> {
>> ... code that might throw ereport(ERROR) ...
>> }
>> PG_FINALLY({
>> cleanup();
>> });
>>
>> See attached patch for how this works out in practice.
+1
> Though I didn't look into individual change, this kind of
> refactoring looks good to me. But the syntax looks
> somewhat.. uh..
>
> I'm not sure it is actually workable, but I suspect that what we
> need here is just a shortcut of 'PG_CATCH();{PG_RE_THROW();}'.
> Something like this:
>
> #define PG_FINALLY() \
> } \
> else \
> { \
> PG_exception_stack = save_exception_stack; \
> error_context_stack = save_context_stack; \
> PG_RE_THROW(); \
> } \
> PG_exception_stack = save_exception_stack; \
> error_context_stack = save_context_stack; \
> {
>
> Which can be used as:
>
> PG_TRY();
> {
> ... code that might throw ereport(ERROR) ...
> }
> PG_FINALLY();
> {
> cleanup();
> }
> PG_TRY_END();
I like this syntax better. We use something very similar in the
pgBackRest project:
TRY_BEGIN()
{
<Do something that might throw an error>
}
CATCH(Error1)
{
<Handle Error1>
}
CATCH(Error2)
{
<Handle Error2>
}
CATCH_ANY()
{
<Handle errors that are not Error1 or Error2>
}
FINALLY()
{
<Cleanup code that runs in all cases>
}
TRY_END();
The syntax works out simpler if the FINALLY is part of the TRY block.
See attached for the implementation.
Regards,
--
-David
david@pgmasters.net