mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
bpo-44839: Raise more specific errors in sqlite3 (GH-27613)
MemoryError raised in user-defined functions will now preserve its type. OverflowError will now be converted to DataError. Previously both were converted to OperationalError.
This commit is contained in:
parent
738ac00a08
commit
7d747f26e6
3 changed files with 79 additions and 37 deletions
|
@ -619,6 +619,29 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Checks the Python exception and sets the appropriate SQLite error code.
|
||||
static void
|
||||
set_sqlite_error(sqlite3_context *context, const char *msg)
|
||||
{
|
||||
assert(PyErr_Occurred());
|
||||
if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
|
||||
sqlite3_result_error_nomem(context);
|
||||
}
|
||||
else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
|
||||
sqlite3_result_error_toobig(context);
|
||||
}
|
||||
else {
|
||||
sqlite3_result_error(context, msg, -1);
|
||||
}
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (state->enable_callback_tracebacks) {
|
||||
PyErr_Print();
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_pysqlite_func_callback(sqlite3_context *context, int argc, sqlite3_value **argv)
|
||||
{
|
||||
|
@ -645,14 +668,7 @@ _pysqlite_func_callback(sqlite3_context *context, int argc, sqlite3_value **argv
|
|||
Py_DECREF(py_retval);
|
||||
}
|
||||
if (!ok) {
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (state->enable_callback_tracebacks) {
|
||||
PyErr_Print();
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined function raised exception", -1);
|
||||
set_sqlite_error(context, "user-defined function raised exception");
|
||||
}
|
||||
|
||||
PyGILState_Release(threadstate);
|
||||
|
@ -676,18 +692,9 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
|
|||
|
||||
if (*aggregate_instance == NULL) {
|
||||
*aggregate_instance = _PyObject_CallNoArg(aggregate_class);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
*aggregate_instance = 0;
|
||||
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (state->enable_callback_tracebacks) {
|
||||
PyErr_Print();
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1);
|
||||
if (!*aggregate_instance) {
|
||||
set_sqlite_error(context,
|
||||
"user-defined aggregate's '__init__' method raised error");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
@ -706,14 +713,8 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
|
|||
Py_DECREF(args);
|
||||
|
||||
if (!function_result) {
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (state->enable_callback_tracebacks) {
|
||||
PyErr_Print();
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
|
||||
set_sqlite_error(context,
|
||||
"user-defined aggregate's 'step' method raised error");
|
||||
}
|
||||
|
||||
error:
|
||||
|
@ -761,14 +762,8 @@ _pysqlite_final_callback(sqlite3_context *context)
|
|||
Py_DECREF(function_result);
|
||||
}
|
||||
if (!ok) {
|
||||
pysqlite_state *state = pysqlite_get_state(NULL);
|
||||
if (state->enable_callback_tracebacks) {
|
||||
PyErr_Print();
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
|
||||
set_sqlite_error(context,
|
||||
"user-defined aggregate's 'finalize' method raised error");
|
||||
}
|
||||
|
||||
/* Restore the exception (if any) of the last call to step(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue