Skip to content

Commit 3bf9a8f

Browse files
authored
Catch PG errors when handling 'catch' section (#690)
Fixes #469
1 parent 9b3ce0f commit 3bf9a8f

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

Diff for: include/pgduckdb/pgduckdb_utils.hpp

+19-11
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,6 @@ struct PgExceptionGuard {
3535
}
3636

3737
~PgExceptionGuard() noexcept {
38-
RestoreStacks();
39-
}
40-
41-
void
42-
RestoreStacks() const noexcept {
4338
PG_exception_stack = _save_exception_stack;
4439
error_context_stack = _save_context_stack;
4540
}
@@ -83,20 +78,33 @@ typename std::invoke_result<Func, FuncArgs...>::type
8378
__PostgresFunctionGuard__(const char *func_name, FuncArgs... args) {
8479
std::lock_guard<std::recursive_mutex> lock(pgduckdb::GlobalProcessLock::GetLock());
8580
MemoryContext ctx = CurrentMemoryContext;
86-
ErrorData *edata = nullptr;
87-
{ // Scope for PG_END_TRY
81+
82+
{ // PG_TRY
8883
PgExceptionGuard g;
8984
sigjmp_buf _local_sigjmp_buf;
9085
if (sigsetjmp(_local_sigjmp_buf, 0) == 0) {
9186
PG_exception_stack = &_local_sigjmp_buf;
9287
return func(std::forward<FuncArgs>(args)...);
93-
} else {
94-
g.RestoreStacks();
95-
CurrentMemoryContext = ctx;
88+
}
89+
}
90+
91+
CurrentMemoryContext = ctx;
92+
93+
ErrorData *edata = nullptr;
94+
{ // PG_CATCH
95+
// Extract the error message (edata) within a PG_TRY block.
96+
PgExceptionGuard g;
97+
sigjmp_buf _local_sigjmp_buf;
98+
if (sigsetjmp(_local_sigjmp_buf, 0) == 0) {
99+
PG_exception_stack = &_local_sigjmp_buf;
100+
96101
edata = CopyErrorData();
97102
FlushErrorState();
103+
} else {
104+
// This is a pretty bad situation - we failed to extract the error message.
105+
throw duckdb::Exception(duckdb::ExceptionType::EXECUTOR, "Failed to extract Postgres error message");
98106
}
99-
} // PG_END_TRY();
107+
} // PG_END_TRY
100108

101109
auto message = duckdb::StringUtil::Format("(PGDuckDB/%s) %s", func_name, pg::GetErrorDataMessage(edata));
102110
throw duckdb::Exception(duckdb::ExceptionType::EXECUTOR, message);

0 commit comments

Comments
 (0)