@@ -88,6 +88,17 @@ inline MaybeLocal<String> Utf8StringMaybeOneByte(Isolate* isolate,
8888 } \
8989 } while (0 )
9090
91+ #define RESET_OR_THROW (isolate, db, stmt, ret ) \
92+ CHECK_ERROR_OR_THROW ((isolate), (db), sqlite3_reset((stmt)), SQLITE_OK, (ret))
93+
94+ // Surface deferred SQLite errors that sqlite3_reset() returns from the prior
95+ // sqlite3_step(). Disables the safety-net reset guard via |needs_reset|.
96+ #define RESET_AND_CHECK (isolate, db, stmt, needs_reset, ret ) \
97+ do { \
98+ (needs_reset) = false ; \
99+ RESET_OR_THROW ((isolate), (db), (stmt), (ret)); \
100+ } while (0 )
101+
91102#define THROW_AND_RETURN_ON_BAD_STATE (env, condition, msg ) \
92103 do { \
93104 if ((condition)) { \
@@ -2893,9 +2904,17 @@ MaybeLocal<Object> StatementExecutionHelper::Run(Environment* env,
28932904 bool use_big_ints) {
28942905 Isolate* isolate = env->isolate ();
28952906 EscapableHandleScope scope (isolate);
2896- sqlite3_step (stmt);
2897- int r = sqlite3_reset (stmt);
2898- CHECK_ERROR_OR_THROW (isolate, db, r, SQLITE_OK, MaybeLocal<Object>());
2907+ bool needs_reset = true ;
2908+ auto reset = OnScopeLeave ([&]() {
2909+ if (needs_reset) sqlite3_reset (stmt);
2910+ });
2911+
2912+ int step_r = sqlite3_step (stmt);
2913+ if (step_r != SQLITE_DONE && step_r != SQLITE_ROW) {
2914+ THROW_ERR_SQLITE_ERROR (isolate, db);
2915+ return MaybeLocal<Object>();
2916+ }
2917+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Object>());
28992918
29002919 sqlite3_int64 last_insert_rowid = sqlite3_last_insert_rowid (db->Connection ());
29012920 sqlite3_int64 changes = sqlite3_changes64 (db->Connection ());
@@ -2969,18 +2988,25 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
29692988 bool use_big_ints) {
29702989 Isolate* isolate = env->isolate ();
29712990 EscapableHandleScope scope (isolate);
2972- auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt); });
2991+ bool needs_reset = true ;
2992+ auto reset = OnScopeLeave ([&]() {
2993+ if (needs_reset) sqlite3_reset (stmt);
2994+ });
29732995
29742996 int r = sqlite3_step (stmt);
2975- if (r == SQLITE_DONE) return scope.Escape (Undefined (isolate));
2997+ if (r == SQLITE_DONE) {
2998+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Value>());
2999+ return scope.Escape (Undefined (isolate));
3000+ }
29763001 if (r != SQLITE_ROW) {
29773002 THROW_ERR_SQLITE_ERROR (isolate, db);
29783003 return MaybeLocal<Value>();
29793004 }
29803005
29813006 int num_cols = sqlite3_column_count (stmt);
29823007 if (num_cols == 0 ) {
2983- return Undefined (isolate);
3008+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3009+ return scope.Escape (Undefined (isolate));
29843010 }
29853011
29863012 LocalVector<Value> row_values (isolate);
@@ -2989,9 +3015,9 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
29893015 return MaybeLocal<Value>();
29903016 }
29913017
3018+ Local<Value> result;
29923019 if (return_arrays) {
2993- return scope.Escape (
2994- Array::New (isolate, row_values.data (), row_values.size ()));
3020+ result = Array::New (isolate, row_values.data (), row_values.size ());
29953021 } else {
29963022 LocalVector<Name> keys (isolate);
29973023 keys.reserve (num_cols);
@@ -3004,9 +3030,12 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
30043030 }
30053031
30063032 DCHECK_EQ (keys.size (), row_values.size ());
3007- return scope. Escape ( Object::New (
3008- isolate, Null (isolate), keys.data (), row_values.data (), num_cols)) ;
3033+ result = Object::New (
3034+ isolate, Null (isolate), keys.data (), row_values.data (), num_cols);
30093035 }
3036+
3037+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3038+ return scope.Escape (result);
30103039}
30113040
30123041void StatementSync::All (const FunctionCallbackInfo<Value>& args) {
@@ -3023,15 +3052,19 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
30233052 return ;
30243053 }
30253054
3026- auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
3027-
3055+ bool needs_reset = true ;
3056+ auto reset = OnScopeLeave ([&]() {
3057+ if (needs_reset) sqlite3_reset (stmt->statement_ );
3058+ });
30283059 Local<Value> result;
30293060 if (StatementExecutionHelper::All (env,
30303061 stmt->db_ .get (),
30313062 stmt->statement_ ,
30323063 stmt->return_arrays_ ,
30333064 stmt->use_big_ints_ )
30343065 .ToLocal (&result)) {
3066+ RESET_AND_CHECK (isolate, stmt->db_ .get (), stmt->statement_ , needs_reset,
3067+ void ());
30353068 args.GetReturnValue ().Set (result);
30363069 }
30373070}
@@ -3470,14 +3503,19 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
34703503 }
34713504 }
34723505
3473- auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
3506+ bool needs_reset = true ;
3507+ auto reset = OnScopeLeave ([&]() {
3508+ if (needs_reset) sqlite3_reset (stmt->statement_ );
3509+ });
34743510 Local<Value> result;
34753511 if (StatementExecutionHelper::All (env,
34763512 stmt->db_ .get (),
34773513 stmt->statement_ ,
34783514 stmt->return_arrays_ ,
34793515 stmt->use_big_ints_ )
34803516 .ToLocal (&result)) {
3517+ RESET_AND_CHECK (isolate, stmt->db_ .get (), stmt->statement_ , needs_reset,
3518+ void ());
34813519 args.GetReturnValue ().Set (result);
34823520 }
34833521}
@@ -3702,7 +3740,10 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
37023740 if (r != SQLITE_ROW) {
37033741 CHECK_ERROR_OR_THROW (
37043742 env->isolate (), iter->stmt_ ->db_ .get (), r, SQLITE_DONE, void ());
3705- sqlite3_reset (iter->stmt_ ->statement_ );
3743+ RESET_OR_THROW (env->isolate (),
3744+ iter->stmt_ ->db_ .get (),
3745+ iter->stmt_ ->statement_ ,
3746+ void ());
37063747 MaybeLocal<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
37073748 Local<Object> result;
37083749 if (NewDictionaryInstanceNullProto (env->context (), iter_template, values)
@@ -3754,7 +3795,10 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
37543795 env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
37553796 Isolate* isolate = env->isolate ();
37563797
3757- sqlite3_reset (iter->stmt_ ->statement_ );
3798+ RESET_OR_THROW (isolate,
3799+ iter->stmt_ ->db_ .get (),
3800+ iter->stmt_ ->statement_ ,
3801+ void ());
37583802 iter->done_ = true ;
37593803
37603804 auto iter_template = getLazyIterTemplate (env);
0 commit comments