* psycopg/pqpath.c (pq_raise): only remove the first 8 characters

of the exception message if it actually gives the severity.

	* psycopg/pqpath.h (pq_resolve_critical): add prototype, since
	this function is being used from connection_int.c.

	* psycopg/psycopg.h: update psyco_set_error() prototype.

	* psycopg/psycopgmodule.c (psyco_errors_init): set pgerror, pgcode
	and cursor class attributes to None on psycopg2.Error so that the
	attributes will always be available (simplifies error handling).
	(psyco_set_error): add const qualifiers to msg, pgerror and pgcode
	arguments.
	Don't bother setting pgerror, pgcode or cursor to None if they are
	not provided -- the class defaults take care of this.
This commit is contained in:
James Henstridge 2007-12-19 14:29:03 +00:00
parent 67afd678b0
commit fd5d2d5238
5 changed files with 58 additions and 24 deletions

View File

@ -1,3 +1,21 @@
2007-12-20 James Henstridge <james@jamesh.id.au>
* psycopg/pqpath.c (pq_raise): only remove the first 8 characters
of the exception message if it actually gives the severity.
* psycopg/pqpath.h (pq_resolve_critical): add prototype, since
this function is being used from connection_int.c.
* psycopg/psycopg.h: update psyco_set_error() prototype.
* psycopg/psycopgmodule.c (psyco_errors_init): set pgerror, pgcode
and cursor class attributes to None on psycopg2.Error so that the
attributes will always be available (simplifies error handling).
(psyco_set_error): add const qualifiers to msg, pgerror and pgcode
arguments.
Don't bother setting pgerror, pgcode or cursor to None if they are
not provided -- the class defaults take care of this.
2007-11-11 Daniele Varrazzo <daniele.varrazzo@gmail.com> 2007-11-11 Daniele Varrazzo <daniele.varrazzo@gmail.com>
* Use escape string syntax for string escape if connected to a * Use escape string syntax for string escape if connected to a

View File

@ -40,18 +40,35 @@
#include "psycopg/pgtypes.h" #include "psycopg/pgtypes.h"
#include "psycopg/pgversion.h" #include "psycopg/pgversion.h"
/* Strip off the severity from a Postgres error message. */
static const char *
strip_severity(const char *msg)
{
if (!msg)
return NULL;
if (strlen(msg) > 8 && (!strncmp(msg, "ERROR: ", 8) ||
!strncmp(msg, "FATAL: ", 8) ||
!strncmp(msg, "PANIC: ", 8)))
return &msg[8];
else
return msg;
}
/* pq_raise - raise a python exception of the right kind /* pq_raise - raise a python exception of the right kind
This function should be called while holding the GIL. */ This function should be called while holding the GIL. */
void static void
pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg) pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc,
const char *msg)
{ {
PyObject *pgc = (PyObject*)curs; PyObject *pgc = (PyObject*)curs;
char *err = NULL; const char *err = NULL;
char *err2 = NULL; const char *err2 = NULL;
char *code = NULL; const char *code = NULL;
char *buf = NULL; char *buf = NULL;
if ((conn == NULL && curs == NULL) || (curs != NULL && conn == NULL)) { if ((conn == NULL && curs == NULL) || (curs != NULL && conn == NULL)) {
@ -108,8 +125,7 @@ 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) err2 = &(err[8]); err2 = strip_severity(err);
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) {

View File

@ -37,5 +37,6 @@ extern int pq_commit(connectionObject *conn);
extern int pq_abort(connectionObject *conn); extern int pq_abort(connectionObject *conn);
extern int pq_is_busy(connectionObject *conn); extern int pq_is_busy(connectionObject *conn);
extern void pq_set_critical(connectionObject *conn, const char *msg); extern void pq_set_critical(connectionObject *conn, const char *msg);
extern PyObject *pq_resolve_critical(connectionObject *conn, int close);
#endif /* !defined(PSYCOPG_PQPATH_H) */ #endif /* !defined(PSYCOPG_PQPATH_H) */

View File

@ -133,8 +133,8 @@ typedef struct {
extern PyObject *psyco_GetDecimalType(void); extern PyObject *psyco_GetDecimalType(void);
/* some utility functions */ /* some utility functions */
extern void psyco_set_error(PyObject *exc, PyObject *curs, char *msg, extern void psyco_set_error(PyObject *exc, PyObject *curs, const char *msg,
char *pgerror, char *pgcode); const char *pgerror, const char *pgcode);
/* Exceptions docstrings */ /* Exceptions docstrings */
#define Error_doc \ #define Error_doc \

View File

@ -481,6 +481,13 @@ psyco_errors_init(void)
*exctable[i].exc = PyErr_NewException(exctable[i].name, base, dict); *exctable[i].exc = PyErr_NewException(exctable[i].name, base, dict);
} }
/* Make pgerror, pgcode and cursor default to None on psycopg
error objects. This simplifies error handling code that checks
these attributes. */
PyObject_SetAttrString(Error, "pgerror", Py_None);
PyObject_SetAttrString(Error, "pgcode", Py_None);
PyObject_SetAttrString(Error, "cursor", Py_None);
} }
void void
@ -518,8 +525,8 @@ psyco_errors_set(PyObject *type)
Create a new error of the given type with extra attributes. */ Create a new error of the given type with extra attributes. */
void void
psyco_set_error(PyObject *exc, PyObject *curs, char *msg, psyco_set_error(PyObject *exc, PyObject *curs, const char *msg,
char *pgerror, char *pgcode) const char *pgerror, const char *pgcode)
{ {
PyObject *t; PyObject *t;
@ -528,26 +535,18 @@ psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
if (err) { if (err) {
if (pgerror) { if (pgerror) {
t = PyString_FromString(pgerror); t = PyString_FromString(pgerror);
PyObject_SetAttrString(err, "pgerror", t);
Py_DECREF(t);
} }
else {
t = Py_None ; Py_INCREF(t);
}
PyObject_SetAttrString(err, "pgerror", t);
Py_DECREF(t);
if (pgcode) { if (pgcode) {
t = PyString_FromString(pgcode); t = PyString_FromString(pgcode);
PyObject_SetAttrString(err, "pgcode", t);
Py_DECREF(t);
} }
else {
t = Py_None ; Py_INCREF(t);
}
PyObject_SetAttrString(err, "pgcode", t);
Py_DECREF(t);
if (curs) if (curs)
PyObject_SetAttrString(err, "cursor", curs); PyObject_SetAttrString(err, "cursor", curs);
else
PyObject_SetAttrString(err, "cursor", Py_None);
PyErr_SetObject(exc, err); PyErr_SetObject(exc, err);
Py_DECREF(err); Py_DECREF(err);
@ -557,7 +556,7 @@ psyco_set_error(PyObject *exc, PyObject *curs, char *msg,
/* Return nonzero if the current one is the main interpreter */ /* Return nonzero if the current one is the main interpreter */
static int static int
psyco_is_main_interp() psyco_is_main_interp(void)
{ {
static PyInterpreterState *main_interp = NULL; /* Cached reference */ static PyInterpreterState *main_interp = NULL; /* Cached reference */
PyInterpreterState *interp; PyInterpreterState *interp;