when a sqlite3_Step call fails, say on a unique key violation of an INSERT statement, the returned error code is SQLITE_ERROR, which is documented. calling sqlite3_errcode at this point, however, also gives the same error, which is not. the correct error, which is SQLITE_CONSTRAINT, is only returned when calling sqlite3_finalize, which may happen at a much later stage in the code.
I believe the error code should be returned right at the point where the error happens, because if it is not, the structure of the code suffers, since the finalization code for a statement needs to be modal.