Skip to content

Commit ea820f8

Browse files
committed
refactor: standardize on (resolve, reject) callback pattern
- Add dispatch_binding_callbacks helper to factorize callback dispatch - Storage/KV bindings now use register_callbacks_with_error (5 args) - __bindingCall passes (resolve, reject) to native functions - Both process_callbacks and process_single_callback use the helper - Errors call reject(Error), success calls resolve(result)
1 parent b6b8b94 commit ea820f8

3 files changed

Lines changed: 157 additions & 93 deletions

File tree

src/runtime/bindings/fetch.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,19 @@ pub fn setup_fetch(
276276
_ => return,
277277
};
278278

279-
let success_cb = args.get(3);
279+
if args.length() < 5 {
280+
return;
281+
}
280282

281-
if !success_cb.is_function() {
283+
let (resolve_cb, reject_cb) = (args.get(3), args.get(4));
284+
285+
if !resolve_cb.is_function() || !reject_cb.is_function() {
282286
return;
283287
}
284288

285-
let success_fn: v8::Local<v8::Function> = success_cb.try_into().unwrap();
286-
let callback_id = register_callback(&state, scope, success_fn);
289+
let resolve_fn: v8::Local<v8::Function> = resolve_cb.try_into().unwrap();
290+
let reject_fn: v8::Local<v8::Function> = reject_cb.try_into().unwrap();
291+
let callback_id = register_callbacks_with_error(&state, scope, resolve_fn, reject_fn);
287292

288293
let _ = state.scheduler_tx.send(SchedulerMessage::BindingStorage(
289294
callback_id,
@@ -337,14 +342,19 @@ pub fn setup_fetch(
337342
_ => return,
338343
};
339344

340-
let success_cb = args.get(3);
345+
if args.length() < 5 {
346+
return;
347+
}
341348

342-
if !success_cb.is_function() {
349+
let (resolve_cb, reject_cb) = (args.get(3), args.get(4));
350+
351+
if !resolve_cb.is_function() || !reject_cb.is_function() {
343352
return;
344353
}
345354

346-
let success_fn: v8::Local<v8::Function> = success_cb.try_into().unwrap();
347-
let callback_id = register_callback(&state, scope, success_fn);
355+
let resolve_fn: v8::Local<v8::Function> = resolve_cb.try_into().unwrap();
356+
let reject_fn: v8::Local<v8::Function> = reject_cb.try_into().unwrap();
357+
let callback_id = register_callbacks_with_error(&state, scope, resolve_fn, reject_fn);
348358

349359
let _ = state.scheduler_tx.send(SchedulerMessage::BindingKv(
350360
callback_id,

src/runtime/bindings/web_api.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,20 +1340,11 @@ pub fn setup_fetch_helpers(scope: &mut v8::PinScope) {
13401340
};
13411341
13421342
// Generic helper for binding calls with Promise wrapper
1343-
// nativeFn: the native binding function to call
1344-
// bindingName: name of the binding
1345-
// method: operation method (get, put, query, etc.)
1346-
// params: parameters object
1347-
// Returns: Promise that resolves with result or rejects with error
1343+
// nativeFn: the native binding function to call (bindingName, method, params, resolve, reject)
1344+
// Returns: Promise that resolves with data or rejects with error
13481345
globalThis.__bindingCall = function(nativeFn, bindingName, method, params) {
13491346
return new Promise((resolve, reject) => {
1350-
nativeFn(bindingName, method, params, (result) => {
1351-
if (!result.success) {
1352-
reject(new Error(result.error));
1353-
} else {
1354-
resolve(result);
1355-
}
1356-
});
1347+
nativeFn(bindingName, method, params, resolve, reject);
13571348
});
13581349
};
13591350

src/runtime/mod.rs

Lines changed: 136 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,55 @@ use v8;
1717

1818
use crate::security::{CustomAllocator, HeapLimitState, install_heap_limit_callback};
1919
use bindings::LogCallback;
20-
use openworkers_core::{RuntimeLimits, WorkerCode};
20+
use openworkers_core::{DatabaseResult, KvResult, RuntimeLimits, StorageResult, WorkerCode};
2121

2222
// Re-export scheduler types
2323
pub use scheduler::{
2424
CallbackId, CallbackMessage, CallbackSender, SchedulerMessage, run_event_loop,
2525
};
2626

27+
/// Helper to dispatch binding result callbacks (resolve/reject pattern)
28+
fn dispatch_binding_callbacks(
29+
scope: &mut v8::PinScope,
30+
callback_id: CallbackId,
31+
resolve_callbacks: &Rc<RefCell<HashMap<CallbackId, v8::Global<v8::Function>>>>,
32+
reject_callbacks: &Rc<RefCell<HashMap<CallbackId, v8::Global<v8::Function>>>>,
33+
error_msg: Option<&str>,
34+
result_value: Option<v8::Local<v8::Value>>,
35+
) {
36+
if let Some(err_msg) = error_msg {
37+
// Error - call reject
38+
let reject_opt = {
39+
let mut cbs = reject_callbacks.borrow_mut();
40+
cbs.remove(&callback_id)
41+
};
42+
// Cleanup resolve
43+
resolve_callbacks.borrow_mut().remove(&callback_id);
44+
45+
if let Some(callback_global) = reject_opt {
46+
let error_msg_val = v8::String::new(scope, err_msg).unwrap();
47+
let error = v8::Exception::error(scope, error_msg_val);
48+
let callback = v8::Local::new(scope, &callback_global);
49+
let recv = v8::undefined(scope);
50+
callback.call(scope, recv.into(), &[error]);
51+
}
52+
} else if let Some(value) = result_value {
53+
// Success - call resolve
54+
let resolve_opt = {
55+
let mut cbs = resolve_callbacks.borrow_mut();
56+
cbs.remove(&callback_id)
57+
};
58+
// Cleanup reject
59+
reject_callbacks.borrow_mut().remove(&callback_id);
60+
61+
if let Some(callback_global) = resolve_opt {
62+
let callback = v8::Local::new(scope, &callback_global);
63+
let recv = v8::undefined(scope);
64+
callback.call(scope, recv.into(), &[value]);
65+
}
66+
}
67+
}
68+
2769
pub struct Runtime {
2870
pub isolate: v8::OwnedIsolate,
2971
pub context: v8::Global<v8::Context>,
@@ -270,54 +312,65 @@ impl Runtime {
270312
}
271313
}
272314
CallbackMessage::StorageResult(callback_id, storage_result) => {
273-
let callback_opt = {
274-
let mut cbs = self.fetch_callbacks.borrow_mut();
275-
cbs.remove(&callback_id)
276-
};
277-
278-
if let Some(callback_global) = callback_opt {
279-
let result_obj = v8::Object::new(scope);
280-
callback_handlers::populate_storage_result(
281-
scope,
282-
result_obj,
283-
storage_result,
284-
);
285-
let callback = v8::Local::new(scope, &callback_global);
286-
let recv = v8::undefined(scope);
287-
callback.call(scope, recv.into(), &[result_obj.into()]);
288-
}
315+
let (error_msg, result_value) =
316+
if let StorageResult::Error(err) = &storage_result {
317+
(Some(err.as_str()), None)
318+
} else {
319+
let result_obj = v8::Object::new(scope);
320+
callback_handlers::populate_storage_result(
321+
scope,
322+
result_obj,
323+
storage_result,
324+
);
325+
(None, Some(result_obj.into()))
326+
};
327+
dispatch_binding_callbacks(
328+
scope,
329+
callback_id,
330+
&self.fetch_callbacks,
331+
&self.fetch_error_callbacks,
332+
error_msg,
333+
result_value,
334+
);
289335
}
290336
CallbackMessage::KvResult(callback_id, kv_result) => {
291-
let callback_opt = {
292-
let mut cbs = self.fetch_callbacks.borrow_mut();
293-
cbs.remove(&callback_id)
294-
};
295-
296-
if let Some(callback_global) = callback_opt {
337+
let (error_msg, result_value) = if let KvResult::Error(err) = &kv_result {
338+
(Some(err.as_str()), None)
339+
} else {
297340
let result_obj = v8::Object::new(scope);
298341
callback_handlers::populate_kv_result(scope, result_obj, kv_result);
299-
let callback = v8::Local::new(scope, &callback_global);
300-
let recv = v8::undefined(scope);
301-
callback.call(scope, recv.into(), &[result_obj.into()]);
302-
}
342+
(None, Some(result_obj.into()))
343+
};
344+
dispatch_binding_callbacks(
345+
scope,
346+
callback_id,
347+
&self.fetch_callbacks,
348+
&self.fetch_error_callbacks,
349+
error_msg,
350+
result_value,
351+
);
303352
}
304353
CallbackMessage::DatabaseResult(callback_id, database_result) => {
305-
let callback_opt = {
306-
let mut cbs = self.fetch_callbacks.borrow_mut();
307-
cbs.remove(&callback_id)
308-
};
309-
310-
if let Some(callback_global) = callback_opt {
311-
let result_obj = v8::Object::new(scope);
312-
callback_handlers::populate_database_result(
313-
scope,
314-
result_obj,
315-
database_result,
316-
);
317-
let callback = v8::Local::new(scope, &callback_global);
318-
let recv = v8::undefined(scope);
319-
callback.call(scope, recv.into(), &[result_obj.into()]);
320-
}
354+
let (error_msg, result_value) =
355+
if let DatabaseResult::Error(err) = &database_result {
356+
(Some(err.as_str()), None)
357+
} else {
358+
let result_obj = v8::Object::new(scope);
359+
callback_handlers::populate_database_result(
360+
scope,
361+
result_obj,
362+
database_result,
363+
);
364+
(None, Some(result_obj.into()))
365+
};
366+
dispatch_binding_callbacks(
367+
scope,
368+
callback_id,
369+
&self.fetch_callbacks,
370+
&self.fetch_error_callbacks,
371+
error_msg,
372+
result_value,
373+
);
321374
}
322375
}
323376
}
@@ -423,46 +476,56 @@ impl Runtime {
423476
}
424477
}
425478
CallbackMessage::StorageResult(callback_id, storage_result) => {
426-
let callback_opt = {
427-
let mut cbs = self.fetch_callbacks.borrow_mut();
428-
cbs.remove(&callback_id)
429-
};
430-
431-
if let Some(callback_global) = callback_opt {
479+
let (error_msg, result_value) = if let StorageResult::Error(err) = &storage_result {
480+
(Some(err.as_str()), None)
481+
} else {
432482
let result_obj = v8::Object::new(scope);
433483
callback_handlers::populate_storage_result(scope, result_obj, storage_result);
434-
let callback = v8::Local::new(scope, &callback_global);
435-
let recv = v8::undefined(scope);
436-
callback.call(scope, recv.into(), &[result_obj.into()]);
437-
}
484+
(None, Some(result_obj.into()))
485+
};
486+
dispatch_binding_callbacks(
487+
scope,
488+
callback_id,
489+
&self.fetch_callbacks,
490+
&self.fetch_error_callbacks,
491+
error_msg,
492+
result_value,
493+
);
438494
}
439495
CallbackMessage::KvResult(callback_id, kv_result) => {
440-
let callback_opt = {
441-
let mut cbs = self.fetch_callbacks.borrow_mut();
442-
cbs.remove(&callback_id)
443-
};
444-
445-
if let Some(callback_global) = callback_opt {
496+
let (error_msg, result_value) = if let KvResult::Error(err) = &kv_result {
497+
(Some(err.as_str()), None)
498+
} else {
446499
let result_obj = v8::Object::new(scope);
447500
callback_handlers::populate_kv_result(scope, result_obj, kv_result);
448-
let callback = v8::Local::new(scope, &callback_global);
449-
let recv = v8::undefined(scope);
450-
callback.call(scope, recv.into(), &[result_obj.into()]);
451-
}
501+
(None, Some(result_obj.into()))
502+
};
503+
dispatch_binding_callbacks(
504+
scope,
505+
callback_id,
506+
&self.fetch_callbacks,
507+
&self.fetch_error_callbacks,
508+
error_msg,
509+
result_value,
510+
);
452511
}
453512
CallbackMessage::DatabaseResult(callback_id, database_result) => {
454-
let callback_opt = {
455-
let mut cbs = self.fetch_callbacks.borrow_mut();
456-
cbs.remove(&callback_id)
457-
};
458-
459-
if let Some(callback_global) = callback_opt {
513+
let (error_msg, result_value) = if let DatabaseResult::Error(err) = &database_result
514+
{
515+
(Some(err.as_str()), None)
516+
} else {
460517
let result_obj = v8::Object::new(scope);
461518
callback_handlers::populate_database_result(scope, result_obj, database_result);
462-
let callback = v8::Local::new(scope, &callback_global);
463-
let recv = v8::undefined(scope);
464-
callback.call(scope, recv.into(), &[result_obj.into()]);
465-
}
519+
(None, Some(result_obj.into()))
520+
};
521+
dispatch_binding_callbacks(
522+
scope,
523+
callback_id,
524+
&self.fetch_callbacks,
525+
&self.fetch_error_callbacks,
526+
error_msg,
527+
result_value,
528+
);
466529
}
467530
}
468531
}

0 commit comments

Comments
 (0)