Commit d4d24d7ff12 for nodejs
commit d4d24d7ff1287276f650c553005dea73b12f1422
Author: Guilherme Araújo <arauujogui@gmail.com>
Date: Tue Oct 20 22:52:14 2026 -0300
sqlite: settle BackupJob through a single exit point
Route every exit through Settle(), which finalizes, settles the
promise and deletes the job once. This also frees the job when
building the progress object fails.
Signed-off-by: Guilherme Araújo <arauujogui@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66912
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc
index b10044a7b15..71cc49c09fe 100644
--- a/src/node_sqlite.cc
+++ b/src/node_sqlite.cc
@@ -645,7 +645,7 @@ class BackupJob : public ThreadPoolWork {
Local<Promise::Resolver> resolver =
Local<Promise::Resolver>::New(env()->isolate(), resolver_);
if (backup_status_ != SQLITE_OK) {
- HandleBackupError(resolver);
+ Settle(resolver, CreateSQLiteError(isolate, dest_.get()), {});
return;
}
@@ -654,7 +654,7 @@ class BackupJob : public ThreadPoolWork {
source_->Connection(),
source_db_.c_str()));
if (!backup_) {
- HandleBackupError(resolver);
+ Settle(resolver, CreateSQLiteError(isolate, dest_.get()), {});
return;
}
@@ -676,7 +676,7 @@ class BackupJob : public ThreadPoolWork {
if (!(backup_status_ == SQLITE_OK || backup_status_ == SQLITE_DONE ||
backup_status_ == SQLITE_BUSY || backup_status_ == SQLITE_LOCKED)) {
- HandleBackupError(resolver, backup_status_);
+ Settle(resolver, CreateSQLiteError(isolate, backup_status_), {});
return;
}
@@ -702,6 +702,7 @@ class BackupJob : public ThreadPoolWork {
env()->remaining_pages_string(),
Integer::New(env()->isolate(), remaining_pages))
.IsNothing()) {
+ Settle(resolver, {}, {});
return;
}
@@ -709,10 +710,7 @@ class BackupJob : public ThreadPoolWork {
TryCatch try_catch(env()->isolate());
USE(fn->Call(env()->context(), Null(env()->isolate()), 1, argv));
if (try_catch.HasCaught()) {
- Local<Value> exception = try_catch.Exception();
- Finalize();
- resolver->Reject(env()->context(), exception).ToChecked();
- delete this;
+ Settle(resolver, try_catch.Exception(), {});
return;
}
}
@@ -723,15 +721,11 @@ class BackupJob : public ThreadPoolWork {
}
if (backup_status_ != SQLITE_DONE) {
- HandleBackupError(resolver);
+ Settle(resolver, CreateSQLiteError(isolate, dest_.get()), {});
return;
}
- Finalize();
- resolver
- ->Resolve(env()->context(), Integer::New(env()->isolate(), total_pages))
- .ToChecked();
- delete this;
+ Settle(resolver, {}, Integer::New(isolate, total_pages));
}
void Finalize() {
@@ -752,29 +746,19 @@ class BackupJob : public ThreadPoolWork {
}
private:
- void HandleBackupError(Local<Promise::Resolver> resolver) {
- Local<Object> e;
- if (!CreateSQLiteError(env()->isolate(), dest_.get()).ToLocal(&e)) {
- Finalize();
- delete this;
- return;
- }
-
+ // The single exit point of a backup. Rejects with `error` if it is set,
+ // otherwise resolves with `value` if it is set. Neither being set means an
+ // exception is already pending. Deletes the job.
+ void Settle(Local<Promise::Resolver> resolver,
+ MaybeLocal<Value> error,
+ Local<Value> value) {
Finalize();
- resolver->Reject(env()->context(), e).ToChecked();
- delete this;
- }
-
- void HandleBackupError(Local<Promise::Resolver> resolver, int errcode) {
- Local<Object> e;
- if (!CreateSQLiteError(env()->isolate(), errcode).ToLocal(&e)) {
- Finalize();
- delete this;
- return;
+ Local<Value> e;
+ if (error.ToLocal(&e)) {
+ resolver->Reject(env()->context(), e).ToChecked();
+ } else if (!value.IsEmpty()) {
+ resolver->Resolve(env()->context(), value).ToChecked();
}
-
- Finalize();
- resolver->Reject(env()->context(), e).ToChecked();
delete this;
}