Skip to content

Conversation

@erlend-aasland
Copy link
Contributor

@erlend-aaslanderlend-aasland commented Sep 2, 2021

@erlend-aasland
Copy link
ContributorAuthor

I see no way to test PyUnicode_DecodeUTF8 errors: UTF8 errors (including too long strings) are handled when we create the statement.

@erlend-aasland
Copy link
ContributorAuthor

@serhiy-storchaka I would like your opinion on this PR, if you don't mind.

@encukou
Copy link
Member

I assumed exceptions in a trace function were ignored on purpose, since there's no way to inform SQLite of the error?
Is it possible to get multiple trace function failures from one sqlite3 call? If so, what happens?

It would be nice to chain the original exception. It's a bit complicated to combine it with the enable_callback_tracebacks mechanism, but you could do something like:

PyObject*type, *value, *traceback; // Clear the error indicator; get references to type, value, tracebackPyErr_Fetch(&type, &value, &traceback); pysqlite_state*state=pysqlite_get_state(NULL); if (state->enable_callback_tracebacks){// Get extra references to type, value & tracebackPy_INCREF(type); Py_INCREF(value); Py_INCREF(traceback); // Restore the error indicator (losing the extra references)PyErr_Restore(type, value, traceback); // Print the error (clearing the error indicator)PyErr_Print()} PyErr_SetString(state->OperationalError, "trace callback raised an exception"); // Chain the original exception as __cause__ (losing our references)_PyErr_ChainExceptions(type, value, traceback);

And since since the user will get the original exception, I wonder if the printing could be skipped.

@erlend-aasland
Copy link
ContributorAuthor

erlend-aasland commented Sep 7, 2021

I assumed exceptions in a trace function were ignored on purpose, since there's no way to inform SQLite of the error?

Maybe so, but how else should we inform the user about bugs in trace functions if not through exceptions?

It would be nice to chain the original exception

Yes, good point.

@encukou
Copy link
Member

how else should we inform the user about bugs in trace functions if not through exceptions?

AFAIK, enable_callback_tracebacks is there exactly for that. It's crude but it seems to work; doing this right won't be an easy change.

Is it possible to get multiple trace function failures from one sqlite3 call?

It is:

>>> conn.executemany('INSERT INTO foo (bar) VALUES (?)', [(1,), (2,), (3,)]) Traceback (most recent call last): File "<stdin>", line 1, in <lambda> ZeroDivisionError: division by zero Traceback (most recent call last): File "<stdin>", line 1, in <lambda> ZeroDivisionError: division by zero Traceback (most recent call last): File "<stdin>", line 1, in <lambda> ZeroDivisionError: division by zero <sqlite3.Cursor object at 0x7faea47f8f80> 

Without the ability to tell SQLite to abort on trace failure, I doubt we can do much better than the current behavior. Getting an exception and having the data inserted seems quite irregular.

@erlend-aasland
Copy link
ContributorAuthor

AFAIK, enable_callback_tracebacks is there exactly for that.

Well, it kinda works, but you won't get an exception. However, getting an exception and having the database modified is worse.

I doubt we can do much better than the current behavior.

I do agree.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@erlend-aasland@encukou@the-knights-who-say-ni@bedevere-bot