@@ -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)) { \
@@ -2989,9 +3000,17 @@ MaybeLocal<Object> StatementExecutionHelper::Run(Environment* env,
29893000 bool use_big_ints) {
29903001 Isolate* isolate = env->isolate ();
29913002 EscapableHandleScope scope (isolate);
2992- sqlite3_step (stmt);
2993- int r = sqlite3_reset (stmt);
2994- CHECK_ERROR_OR_THROW (isolate, db, r, SQLITE_OK , MaybeLocal<Object>());
3003+ bool needs_reset = true ;
3004+ auto reset = OnScopeLeave ([&]() {
3005+ if (needs_reset) sqlite3_reset (stmt);
3006+ });
3007+
3008+ int step_r = sqlite3_step (stmt);
3009+ if (step_r != SQLITE_DONE && step_r != SQLITE_ROW ) {
3010+ THROW_ERR_SQLITE_ERROR (isolate, db);
3011+ return MaybeLocal<Object>();
3012+ }
3013+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Object>());
29953014
29963015 sqlite3_int64 last_insert_rowid = sqlite3_last_insert_rowid (db->Connection ());
29973016 sqlite3_int64 changes = sqlite3_changes64 (db->Connection ());
@@ -3065,18 +3084,25 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
30653084 bool use_big_ints) {
30663085 Isolate* isolate = env->isolate ();
30673086 EscapableHandleScope scope (isolate);
3068- auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt); });
3087+ bool needs_reset = true ;
3088+ auto reset = OnScopeLeave ([&]() {
3089+ if (needs_reset) sqlite3_reset (stmt);
3090+ });
30693091
30703092 int r = sqlite3_step (stmt);
3071- if (r == SQLITE_DONE ) return scope.Escape (Undefined (isolate));
3093+ if (r == SQLITE_DONE ) {
3094+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3095+ return scope.Escape (Undefined (isolate));
3096+ }
30723097 if (r != SQLITE_ROW ) {
30733098 THROW_ERR_SQLITE_ERROR (isolate, db);
30743099 return MaybeLocal<Value>();
30753100 }
30763101
30773102 int num_cols = sqlite3_column_count (stmt);
30783103 if (num_cols == 0 ) {
3079- return Undefined (isolate);
3104+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3105+ return scope.Escape (Undefined (isolate));
30803106 }
30813107
30823108 LocalVector<Value> row_values (isolate);
@@ -3085,9 +3111,9 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
30853111 return MaybeLocal<Value>();
30863112 }
30873113
3114+ Local<Value> result;
30883115 if (return_arrays) {
3089- return scope.Escape (
3090- Array::New (isolate, row_values.data (), row_values.size ()));
3116+ result = Array::New (isolate, row_values.data (), row_values.size ());
30913117 } else {
30923118 LocalVector<Name> keys (isolate);
30933119 keys.reserve (num_cols);
@@ -3100,9 +3126,12 @@ MaybeLocal<Value> StatementExecutionHelper::Get(Environment* env,
31003126 }
31013127
31023128 DCHECK_EQ (keys.size (), row_values.size ());
3103- return scope. Escape ( Object::New (
3104- isolate, Null (isolate), keys.data (), row_values.data (), num_cols)) ;
3129+ result = Object::New (
3130+ isolate, Null (isolate), keys.data (), row_values.data (), num_cols);
31053131 }
3132+
3133+ RESET_AND_CHECK (isolate, db, stmt, needs_reset, MaybeLocal<Value>());
3134+ return scope.Escape (result);
31063135}
31073136
31083137void StatementSync::All (const FunctionCallbackInfo<Value>& args) {
@@ -3119,15 +3148,19 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
31193148 return ;
31203149 }
31213150
3122- auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
3123-
3151+ bool needs_reset = true ;
3152+ auto reset = OnScopeLeave ([&]() {
3153+ if (needs_reset) sqlite3_reset (stmt->statement_ );
3154+ });
31243155 Local<Value> result;
31253156 if (StatementExecutionHelper::All (env,
31263157 stmt->db_ .get (),
31273158 stmt->statement_ ,
31283159 stmt->return_arrays_ ,
31293160 stmt->use_big_ints_ )
31303161 .ToLocal (&result)) {
3162+ RESET_AND_CHECK (
3163+ isolate, stmt->db_ .get (), stmt->statement_ , needs_reset, void ());
31313164 args.GetReturnValue ().Set (result);
31323165 }
31333166}
@@ -3566,14 +3599,19 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
35663599 }
35673600 }
35683601
3569- auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
3602+ bool needs_reset = true ;
3603+ auto reset = OnScopeLeave ([&]() {
3604+ if (needs_reset) sqlite3_reset (stmt->statement_ );
3605+ });
35703606 Local<Value> result;
35713607 if (StatementExecutionHelper::All (env,
35723608 stmt->db_ .get (),
35733609 stmt->statement_ ,
35743610 stmt->return_arrays_ ,
35753611 stmt->use_big_ints_ )
35763612 .ToLocal (&result)) {
3613+ RESET_AND_CHECK (
3614+ isolate, stmt->db_ .get (), stmt->statement_ , needs_reset, void ());
35773615 args.GetReturnValue ().Set (result);
35783616 }
35793617}
@@ -3800,7 +3838,10 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
38003838 if (r != SQLITE_ROW ) {
38013839 CHECK_ERROR_OR_THROW (
38023840 env->isolate (), iter->stmt_ ->db_ .get (), r, SQLITE_DONE , void ());
3803- sqlite3_reset (iter->stmt_ ->statement_ );
3841+ RESET_OR_THROW (env->isolate (),
3842+ iter->stmt_ ->db_ .get (),
3843+ iter->stmt_ ->statement_ ,
3844+ void ());
38043845 iter->done_ = true ;
38053846 MaybeLocal<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
38063847 Local<Object> result;
@@ -3853,7 +3894,8 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
38533894 env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
38543895 Isolate* isolate = env->isolate ();
38553896
3856- sqlite3_reset (iter->stmt_ ->statement_ );
3897+ RESET_OR_THROW (
3898+ isolate, iter->stmt_ ->db_ .get (), iter->stmt_ ->statement_ , void ());
38573899 iter->done_ = true ;
38583900
38593901 auto iter_template = getLazyIterTemplate (env);
0 commit comments