mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-02-07 21:00:33 +03:00
Extra attributes for ProgrammingError exception.
This commit is contained in:
parent
d5674253ca
commit
96ff591d79
|
@ -1,5 +1,9 @@
|
||||||
2006-01-05 Federico Di Gregorio <fog@initd.org>
|
2006-01-05 Federico Di Gregorio <fog@initd.org>
|
||||||
|
|
||||||
|
* psycopg/psycopgmodule.c (psyco_set_error): added function to set extra
|
||||||
|
parameters on ProgrammingError instances. Also modified all occurances of
|
||||||
|
PyErr_SetString(ProgrammingError,...) to psycopg_set_error().
|
||||||
|
|
||||||
* setup.{cfg,py}: we now use pg_config to locate PostgreSQL libraries
|
* setup.{cfg,py}: we now use pg_config to locate PostgreSQL libraries
|
||||||
and headers (modified patch from lbruno, see #70.)
|
and headers (modified patch from lbruno, see #70.)
|
||||||
|
|
||||||
|
|
|
@ -241,14 +241,15 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
if (self->conn->async_cursor != NULL
|
if (self->conn->async_cursor != NULL
|
||||||
&& self->conn->async_cursor != (PyObject*)self) {
|
&& self->conn->async_cursor != (PyObject*)self) {
|
||||||
pthread_mutex_unlock(&(self->conn->lock));
|
pthread_mutex_unlock(&(self->conn->lock));
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"asynchronous query already in execution");
|
"asynchronous query already in execution", NULL, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(self->conn->lock));
|
pthread_mutex_unlock(&(self->conn->lock));
|
||||||
|
|
||||||
if (!PyObject_IsTrue(operation)) {
|
if (!PyObject_IsTrue(operation)) {
|
||||||
PyErr_SetString(ProgrammingError, "can't execute an empty query");
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
|
"can't execute an empty query", NULL, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +335,8 @@ _psyco_curs_execute(cursorObject *self,
|
||||||
if (!strcmp(s, "not enough arguments for format string")
|
if (!strcmp(s, "not enough arguments for format string")
|
||||||
|| !strcmp(s, "not all arguments converted")) {
|
|| !strcmp(s, "not all arguments converted")) {
|
||||||
Dprintf("psyco_curs_execute: -> got a match");
|
Dprintf("psyco_curs_execute: -> got a match");
|
||||||
PyErr_SetString(ProgrammingError, s);
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
|
s, NULL, NULL);
|
||||||
pe = 1;
|
pe = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,18 +405,19 @@ psyco_curs_execute(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
if (self->query != Py_None) {
|
if (self->query != Py_None) {
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"can't call .execute() on named cursors more than once");
|
"can't call .execute() on named cursors more than once",
|
||||||
|
NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (self->conn->isolation_level == 0) {
|
if (self->conn->isolation_level == 0) {
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"can't use a named cursor outside of transactions");
|
"can't use a named cursor outside of transactions", NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (self->conn->mark != self->mark) {
|
if (self->conn->mark != self->mark) {
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"named cursor isn't valid anymore");
|
"named cursor isn't valid anymore", NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,8 +452,8 @@ psyco_curs_executemany(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
EXC_IF_CURS_CLOSED(self);
|
EXC_IF_CURS_CLOSED(self);
|
||||||
|
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"can't call .executemany() on named cursors");
|
"can't call .executemany() on named cursors", NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +536,8 @@ psyco_curs_mogrify(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (!strcmp(s, "not enough arguments for format string")
|
if (!strcmp(s, "not enough arguments for format string")
|
||||||
|| !strcmp(s, "not all arguments converted")) {
|
|| !strcmp(s, "not all arguments converted")) {
|
||||||
Dprintf("psyco_curs_execute: -> got a match");
|
Dprintf("psyco_curs_execute: -> got a match");
|
||||||
PyErr_SetString(ProgrammingError, s);
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
|
s, NULL, NULL);
|
||||||
pe = 1;
|
pe = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,8 +589,8 @@ _psyco_curs_prefetch(cursorObject *self)
|
||||||
if (self->conn->async_cursor != NULL
|
if (self->conn->async_cursor != NULL
|
||||||
&& self->conn->async_cursor != (PyObject*)self) {
|
&& self->conn->async_cursor != (PyObject*)self) {
|
||||||
pthread_mutex_unlock(&(self->conn->lock));
|
pthread_mutex_unlock(&(self->conn->lock));
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"asynchronous fetch by wrong cursor");
|
"asynchronous fetch by wrong cursor", NULL, NULL);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(self->conn->lock));
|
pthread_mutex_unlock(&(self->conn->lock));
|
||||||
|
@ -880,8 +884,8 @@ psyco_curs_callproc(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
EXC_IF_CURS_CLOSED(self);
|
EXC_IF_CURS_CLOSED(self);
|
||||||
|
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"can't call .callproc() on named cursors");
|
"can't call .callproc() on named cursors", NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,14 +1007,14 @@ psyco_curs_scroll(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
} else if (strcmp( mode, "absolute") == 0) {
|
} else if (strcmp( mode, "absolute") == 0) {
|
||||||
newpos = value;
|
newpos = value;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(ProgrammingError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"scroll mode must be 'relative' or 'absolute'");
|
"scroll mode must be 'relative' or 'absolute'", NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newpos < 0 || newpos >= self->rowcount ) {
|
if (newpos < 0 || newpos >= self->rowcount ) {
|
||||||
PyErr_SetString(PyExc_IndexError,
|
psyco_set_error(ProgrammingError, (PyObject*)self,
|
||||||
"scroll destination out of bounds");
|
"scroll destination out of bounds", NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* else set the right exception and return NULL */
|
/* else set the right exception and return NULL */
|
||||||
PyErr_SetString(ProgrammingError, "can't adapt");
|
psyco_set_error(ProgrammingError, NULL, "can't adapt", NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,15 @@
|
||||||
void
|
void
|
||||||
pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
|
pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
|
||||||
{
|
{
|
||||||
|
PyObject *pgc = (PyObject*)curs;
|
||||||
|
|
||||||
char *err = NULL;
|
char *err = NULL;
|
||||||
|
char *err2 = NULL;
|
||||||
char *code = NULL;
|
char *code = NULL;
|
||||||
|
char *buf = NULL;
|
||||||
|
|
||||||
if ((conn == NULL && curs == NULL) || (curs != NULL && conn == NULL)) {
|
if ((conn == NULL && curs == NULL) || (curs != NULL && conn == NULL)) {
|
||||||
PyErr_SetString(Error,
|
PyErr_SetString(Error, "psycopg went psycotic and raised a null error");
|
||||||
"psycopg went psycotic and raised a null error");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,18 +107,29 @@ pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to remove the initial "ERROR: " part from the postgresql error */
|
/* try to remove the initial "ERROR: " part from the postgresql error */
|
||||||
if (err && strlen(err) > 8) err = &(err[8]);
|
if (err && strlen(err) > 8) err2 = &(err[8]);
|
||||||
|
else err2 = err;
|
||||||
|
|
||||||
/* if msg is not NULL, add it to the error message, after a '\n' */
|
/* if msg is not NULL, add it to the error message, after a '\n' */
|
||||||
if (msg && code) {
|
if (msg && code) {
|
||||||
PyErr_Format(exc, "[%s] %s\n%s", code, err, msg);
|
int len = strlen(code) + strlen(err) + strlen(msg) + 5;
|
||||||
|
if ((buf = PyMem_Malloc(len))) {
|
||||||
|
snprintf(buf, len, "[%s] %s\n%s", code, err2, msg);
|
||||||
|
psyco_set_error(exc, pgc, buf, err, code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (msg) {
|
else if (msg) {
|
||||||
PyErr_Format(exc, "%s\n%s", err, msg);
|
int len = strlen(err) + strlen(msg) + 2;
|
||||||
|
if ((buf = PyMem_Malloc(len))) {
|
||||||
|
snprintf(buf, len, "%s\n%s", err2, msg);
|
||||||
|
psyco_set_error(exc, pgc, buf, err, code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyErr_SetString(exc, err);
|
psyco_set_error(exc, pgc, err2, err, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buf != NULL) PyMem_Free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pq_set_critical, pq_resolve_critical - manage critical errors
|
/* pq_set_critical, pq_resolve_critical - manage critical errors
|
||||||
|
|
|
@ -100,6 +100,10 @@ typedef struct {
|
||||||
/* the Decimal type, used by the DECIMAL typecaster */
|
/* the Decimal type, used by the DECIMAL typecaster */
|
||||||
extern PyObject *decimalType;
|
extern PyObject *decimalType;
|
||||||
|
|
||||||
|
/* some utility functions */
|
||||||
|
extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
|
||||||
|
char *pgerror, char *pgcode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -366,6 +366,46 @@ psyco_errors_set(PyObject *type)
|
||||||
PyObject_SetAttrString(type, "NotSupportedError", NotSupportedError);
|
PyObject_SetAttrString(type, "NotSupportedError", NotSupportedError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* psyco_error_new
|
||||||
|
|
||||||
|
Create a new error of the given type with extra attributes. */
|
||||||
|
|
||||||
|
void
|
||||||
|
psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
|
||||||
|
char *pgerror, char *pgcode)
|
||||||
|
{
|
||||||
|
PyObject *t;
|
||||||
|
|
||||||
|
PyObject *err = PyObject_CallFunction(exc, "s", msg);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
if (pgerror) {
|
||||||
|
t = PyString_FromString(pgerror);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t = Py_None ; Py_INCREF(t);
|
||||||
|
}
|
||||||
|
PyObject_SetAttrString(err, "pgerror", t);
|
||||||
|
Py_DECREF(t);
|
||||||
|
|
||||||
|
if (pgcode) {
|
||||||
|
t = PyString_FromString(pgcode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t = Py_None ; Py_INCREF(t);
|
||||||
|
}
|
||||||
|
PyObject_SetAttrString(err, "pgcode", t);
|
||||||
|
Py_DECREF(t);
|
||||||
|
|
||||||
|
if (curs)
|
||||||
|
PyObject_SetAttrString(err, "cursor", curs);
|
||||||
|
else
|
||||||
|
PyObject_SetAttrString(err, "cursor", Py_None);
|
||||||
|
|
||||||
|
PyErr_SetObject(exc, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* psyco_decimal_init
|
/* psyco_decimal_init
|
||||||
|
|
||||||
Initialize the module's pointer to the decimal type. */
|
Initialize the module's pointer to the decimal type. */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user