diff options
author | Gerhard Häring <gh@ghaering.de> | 2008-02-29 22:22:09 (GMT) |
---|---|---|
committer | Gerhard Häring <gh@ghaering.de> | 2008-02-29 22:22:09 (GMT) |
commit | 873d9ff84cf991a4a63d659479ab97724e44283d (patch) | |
tree | c809464127100eab12ba8223653c2ad06fed1fda | |
parent | 20c892db1012a84431c75d21565e4a6af538cfed (diff) | |
download | cpython-873d9ff84cf991a4a63d659479ab97724e44283d.zip cpython-873d9ff84cf991a4a63d659479ab97724e44283d.tar.gz cpython-873d9ff84cf991a4a63d659479ab97724e44283d.tar.bz2 |
Make sure we get usable error messages when text could not be decoded when fetched from the database.
-rw-r--r-- | Lib/sqlite3/test/regression.py | 14 | ||||
-rw-r--r-- | Modules/_sqlite/cursor.c | 16 |
2 files changed, 29 insertions, 1 deletions
diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index df2a6fb..4a68d9d 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -79,6 +79,20 @@ class RegressionTests(unittest.TestCase): cur.fetchone() cur.fetchone() + def CheckErrorMsgDecodeError(self): + # When porting the module to Python 3.0, the error message about + # decoding errors disappeared. This verifies they're back again. + failure = None + try: + self.con.execute("select 'xxx' || ? || 'yyy' colname", (bytes(bytearray([250])),)).fetchone() + failure = "should have raised an OperationalError with detailed description" + except sqlite.OperationalError as e: + msg = e.args[0] + if not msg.startswith("Could not decode to UTF-8 column 'colname' with text 'xxx"): + failure = "OperationalError did not have expected description text" + if failure: + self.fail(failure) + def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") return unittest.TestSuite((regression_suite,)) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 6b81851..0bd317a 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -295,6 +295,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) const char* val_str; char buf[200]; const char* colname; + PyObject* buf_bytes; + PyObject* error_obj; Py_BEGIN_ALLOW_THREADS numcols = sqlite3_data_count(self->statement->st); @@ -363,7 +365,19 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) } PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'", colname , val_str); - PyErr_SetString(pysqlite_OperationalError, buf); + buf_bytes = PyBytes_FromStringAndSize(buf, strlen(buf)); + if (!buf_bytes) { + PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8"); + } else { + error_obj = PyUnicode_FromEncodedObject(buf_bytes, "ascii", "replace"); + if (!error_obj) { + PyErr_SetString(pysqlite_OperationalError, "Could not decode to UTF-8"); + Py_DECREF(error_obj); + } else { + PyErr_SetObject(pysqlite_OperationalError, error_obj); + } + Py_DECREF(buf_bytes); + } } } else if (self->connection->text_factory == (PyObject*)&PyString_Type) { converted = PyString_FromString(val_str); |