Обсуждение: Is there public API to fetch errcode?

Поиск
Список
Период
Сортировка

Is there public API to fetch errcode?

От
Sergey Fukanchik
Дата:
Hi Postgres hackers,
ereport() can accept an error code. For example:
             ereport(FATAL,
                     (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
                      errmsg("number of requested standby connections 
exceeds \"max_wal_senders\" (currently %d)",
                             max_wal_senders)));

In this case the error happens during connection initialization, outside 
of an SQL query. I.e. PGresult is not available.

I suspect that the error code is available on the client as 
PGconn->last_sqlstate however it is private and I can't find any public 
API to fetch it.

Does libpq have an API to extract this code?

---

Sergey




Re: Is there public API to fetch errcode?

От
Tom Lane
Дата:
Sergey Fukanchik <s.fukanchik@postgrespro.ru> writes:
> Does libpq have an API to extract this code?

PQresultErrorField(res, PG_DIAG_SQLSTATE) should do, no?

            regards, tom lane



Re: Is there public API to fetch errcode?

От
"David G. Johnston"
Дата:
On Sun, Oct 12, 2025 at 1:27 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Sergey Fukanchik <s.fukanchik@postgrespro.ru> writes:
> Does libpq have an API to extract this code?

PQresultErrorField(res, PG_DIAG_SQLSTATE) should do, no?


I believe the call flow is the following - no "res"/result is ever constructed:

PGconn *PQconnectdb(const char *conninfo);
ConnStatusType PQstatus(const PGconn *conn);
// Connection_Bad
char *PQerrorMessage(const PGconn *conn);
// Obtains the error message; but there seems to be no equivalent of PQresultErrorField (e.g. PQconnErrorField) to obtain the SQLState field component thereof

David J.

Re: Is there public API to fetch errcode?

От
Tom Lane
Дата:
"David G. Johnston" <david.g.johnston@gmail.com> writes:
> On Sun, Oct 12, 2025 at 1:27 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> PQresultErrorField(res, PG_DIAG_SQLSTATE) should do, no?

> I believe the call flow is the following - no "res"/result is ever
> constructed:

Hmm ... no, we do construct a PGresult containing the error (including
SQLSTATE), because pqGetErrorNotice3 is what's used to read the
server's error response.  But it looks like for a connection-time
failure, PQconnectPoll clears it before returning.

In principle maybe we could keep that around, allowing the application
to do PQgetResult from the failed connection object.  Seems like it'd
be a bit of a mess though.  Also, given all the logic that's there
to retry different server addresses etc, it's not clear which failure
result to preserve.  We sidestep that question so far as the textual
PQerrorMessage output is concerned by concatenating all the failures,
but that's not workable for PGresults.

            regards, tom lane



Re: Is there public API to fetch errcode?

От
Sergey Fukanchik
Дата:
sqlstate is saved into conn->last_sqlstate along with the error message
in pqGetErrorNotice3:

         if (id == PG_DIAG_SQLSTATE)
             strlcpy(conn->last_sqlstate, workBuf.data,
                     sizeof(conn->last_sqlstate));

is this usable? Can it be extracted somehow?

---

Sergey




Re: Is there public API to fetch errcode?

От
Tom Lane
Дата:
Sergey Fukanchik <s.fukanchik@postgrespro.ru> writes:
> sqlstate is saved into conn->last_sqlstate along with the error message 
> in pqGetErrorNotice3:
>          if (id == PG_DIAG_SQLSTATE)
>              strlcpy(conn->last_sqlstate, workBuf.data,
>                      sizeof(conn->last_sqlstate));
> is this usable? Can it be extracted somehow?

It is not exposed, and if it were you'd have the same problem of lack
of context: you don't know which connection attempt set the value,
nor whether that's the most interesting failure.

If we wanted to up our game in this area, I'd envision making it
possible to extract a PGresult or PGresult-like structure for each
connection attempt that libpq made.  It'd need to carry the connection
details (server address, encryption options, etc) as well as the
failure info.  Not a trivial project, but doubtless do-able if
someone cared to put in the effort.

Of course, that just begs the question of what an application
would do with this data if it had it.

            regards, tom lane



Re: Is there public API to fetch errcode?

От
Sergey Fukanchik
Дата:
So the difference between conn->errorMessage and conn->last_sqlstate is 
that erorrMessage is appended and last_sqstate is overwritten.

And it seems that changing this is not easy.

As to why I want this - there are several reasons for connection to be 
rejected, like ERRCODE_CANNOT_CONNECT_NOW, ERRCODE_TOO_MANY_CONNECTIONS, 
ERRCODE_INSUFFICIENT_PRIVILEGE, ERRCODE_DATA_CORRUPTED etc

I would like my client to behave differently based on a particular 
errcode - sometimes wait and retry, sometimes choose another server, 
sometimes just fail.

It would be perfect if I could simply configure libpq to do such 
reactions automatically for me, but designing this properly seems to be 
even harder than exposing connection sqlstate.

SQLSTATE codes are locale independent and it would help a lot if I could 
use them instead of relying on localized messages.

---

Sergey