pg: More verbose error traces
Partly because some errors currently appeared to come from within FU::PG itself, which is useless, and partly because it's common to wrap database access methods, while that's exactly the kind of operation where you *really* want to know where the error originated from. (Source: too much time wasted debugging VNDB errors)
This commit is contained in:
parent
96aee880ce
commit
7c8473533d
4 changed files with 46 additions and 27 deletions
30
c/pgconn.c
30
c/pgconn.c
|
|
@ -142,11 +142,11 @@ static fupg_conn *fupg_get_transaction(pTHX_ SV *sv) {
|
|||
|
||||
v = av_fetch(av, 1, 0);
|
||||
if (!v || !*v) goto invalid;
|
||||
if (!SvOK(*v)) croak("Invalid attempt to run a query on a transaction that has already finished");
|
||||
if (c->cookie != SvUV(*v)) croak("Invalid cross-transaction operation");
|
||||
if (!SvOK(*v)) fu_confess("Invalid attempt to run a query on a transaction that has already finished");
|
||||
if (c->cookie != SvUV(*v)) fu_confess("Invalid cross-transaction operation");
|
||||
return c;
|
||||
invalid:
|
||||
croak("invalid transaction object");
|
||||
fu_confess("invalid transaction object");
|
||||
}
|
||||
|
||||
/* Read a Perl value from a PGresult.
|
||||
|
|
@ -196,7 +196,7 @@ static SV *fupg_q(pTHX_ fupg_conn *c, const char *query, I32 ax, I32 argc) {
|
|||
|
||||
static void fupg_st_prepare(pTHX_ fupg_st *st) {
|
||||
if (st->describe) return;
|
||||
if (st->prepared) croak("invalid attempt to re-prepare invalid statement");
|
||||
if (st->prepared) fu_confess("invalid attempt to re-prepare invalid statement");
|
||||
|
||||
/* TODO: This is where we check for any cached prepared statements */
|
||||
|
||||
|
|
@ -253,7 +253,7 @@ static void fupg_st_check_dupcols(pTHX_ PGresult *r) {
|
|||
int len = -strlen(key);
|
||||
if (hv_exists(hv, key, len)) {
|
||||
SvREFCNT_dec((SV *)hv);
|
||||
croak("Query returns multiple columns with the same name ('%s')", key);
|
||||
fu_confess("Query returns multiple columns with the same name ('%s')", key);
|
||||
}
|
||||
hv_store(hv, key, len, &PL_sv_yes, 0);
|
||||
}
|
||||
|
|
@ -264,7 +264,7 @@ static void fupg_st_execute(pTHX_ fupg_st *st) {
|
|||
/* Disallow fetching the results more than once. I don't see a reason why
|
||||
* someone would need that and disallowing it leaves room for fetching the
|
||||
* results in a streaming fashion without breaking API compat. */
|
||||
if (st->result) croak("Invalid attempt to execute statement multiple times");
|
||||
if (st->result) fu_confess("Invalid attempt to execute statement multiple times");
|
||||
|
||||
/* TODO: prepare can be skipped when prepared statement caching is disabled and (text-format queries or no bind params) */
|
||||
fupg_st_prepare(aTHX_ st);
|
||||
|
|
@ -302,10 +302,10 @@ static SV *fupg_st_exec(pTHX_ fupg_st *st) {
|
|||
|
||||
static SV *fupg_st_val(pTHX_ fupg_st *st) {
|
||||
fupg_st_prepare(aTHX_ st);
|
||||
if (PQnfields(st->describe) > 1) croak("Invalid use of $st->val() on query returning more than one column");
|
||||
if (PQnfields(st->describe) == 0) croak("Invalid use of $st->val() on query returning no data");
|
||||
if (PQnfields(st->describe) > 1) fu_confess("Invalid use of $st->val() on query returning more than one column");
|
||||
if (PQnfields(st->describe) == 0) fu_confess("Invalid use of $st->val() on query returning no data");
|
||||
fupg_st_execute(aTHX_ st);
|
||||
if (PQntuples(st->result) > 1) croak("Invalid use of $st->val() on query returning more than one row");
|
||||
if (PQntuples(st->result) > 1) fu_confess("Invalid use of $st->val() on query returning more than one row");
|
||||
SV *sv = PQntuples(st->result) == 0 ? newSV(0) : fupg_val(aTHX_ st->result, 0, 0);
|
||||
return sv_2mortal(sv);
|
||||
}
|
||||
|
|
@ -313,8 +313,8 @@ static SV *fupg_st_val(pTHX_ fupg_st *st) {
|
|||
static I32 fupg_st_rowl(pTHX_ fupg_st *st, I32 ax) {
|
||||
dSP;
|
||||
fupg_st_execute(aTHX_ st);
|
||||
if (PQntuples(st->result) == 0) croak("Invalid use of $st->rowl() on query returning zero rows");
|
||||
if (PQntuples(st->result) > 1) croak("Invalid use of $st->rowl() on query returning more than one row");
|
||||
if (PQntuples(st->result) == 0) fu_confess("Invalid use of $st->rowl() on query returning zero rows");
|
||||
if (PQntuples(st->result) > 1) fu_confess("Invalid use of $st->rowl() on query returning more than one row");
|
||||
if (GIMME_V != G_LIST) {
|
||||
ST(0) = sv_2mortal(newSViv(PQnfields(st->result)));
|
||||
return 1;
|
||||
|
|
@ -328,8 +328,8 @@ static I32 fupg_st_rowl(pTHX_ fupg_st *st, I32 ax) {
|
|||
|
||||
static SV *fupg_st_rowa(pTHX_ fupg_st *st) {
|
||||
fupg_st_execute(aTHX_ st);
|
||||
if (PQntuples(st->result) == 0) croak("Invalid use of $st->rowl() on query returning zero rows");
|
||||
if (PQntuples(st->result) > 1) croak("Invalid use of $st->rowl() on query returning more than one row");
|
||||
if (PQntuples(st->result) == 0) fu_confess("Invalid use of $st->rowl() on query returning zero rows");
|
||||
if (PQntuples(st->result) > 1) fu_confess("Invalid use of $st->rowl() on query returning more than one row");
|
||||
int i, nfields = PQnfields(st->result);
|
||||
AV *av = newAV_alloc_x(nfields);
|
||||
SV *sv = sv_2mortal(newRV_noinc((SV *)av));
|
||||
|
|
@ -341,8 +341,8 @@ static SV *fupg_st_rowh(pTHX_ fupg_st *st) {
|
|||
fupg_st_prepare(aTHX_ st);
|
||||
fupg_st_check_dupcols(aTHX_ st->describe);
|
||||
fupg_st_execute(aTHX_ st);
|
||||
if (PQntuples(st->result) == 0) croak("Invalid use of $st->rowh() on query returning zero rows");
|
||||
if (PQntuples(st->result) > 1) croak("Invalid use of $st->rowh() on query returning more than one row");
|
||||
if (PQntuples(st->result) == 0) fu_confess("Invalid use of $st->rowh() on query returning zero rows");
|
||||
if (PQntuples(st->result) > 1) fu_confess("Invalid use of $st->rowh() on query returning more than one row");
|
||||
int i, nfields = PQnfields(st->result);
|
||||
HV *hv = newHV();
|
||||
SV *sv = sv_2mortal(newRV_noinc((SV *)hv));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue