Skip to content

Commit 6b8b633

Browse files
committed
test: cover async next callback failures
Signed-off-by: Will Killian <wkillian@nvidia.com>
1 parent e585ac8 commit 6b8b633

3 files changed

Lines changed: 35 additions & 0 deletions

File tree

crates/ffi/nemo_relay.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2649,6 +2649,9 @@ NemoRelayStatus nemo_relay_async_next_invoke(const struct NemoRelayAsyncNext *ne
26492649

26502650
/**
26512651
* Invoke the next execution layer and report its result through a callback.
2652+
*
2653+
* A non-`Ok` return means invocation was not scheduled and `callback` is
2654+
* never invoked; the caller owns any state it allocated for `user_data`.
26522655
*/
26532656
NemoRelayStatus nemo_relay_async_next_invoke_callback(const struct NemoRelayAsyncNext *next,
26542657
const char *invocation_json,

crates/ffi/src/callable.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@ pub unsafe extern "C" fn nemo_relay_async_next_invoke(
328328
}
329329

330330
/// Invoke the next execution layer and report its result through a callback.
331+
///
332+
/// A non-`Ok` return means invocation was not scheduled and `callback` is
333+
/// never invoked; the caller owns any state it allocated for `user_data`.
331334
#[allow(clippy::missing_safety_doc)] // The shared C ABI safety contract applies.
332335
#[unsafe(no_mangle)]
333336
pub unsafe extern "C" fn nemo_relay_async_next_invoke_callback(

crates/ffi/tests/unit/callable_private_tests.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,33 @@ fn async_next_callback_reports_tool_llm_and_stream_results() {
298298
assert_eq!(runtime.block_on(receiver).unwrap().unwrap(), expected);
299299
unsafe { nemo_relay_async_next_release(next_ref) };
300300
}
301+
302+
let next = Arc::new(NemoRelayAsyncNext {
303+
inner: AsyncNextInner::Tool(Arc::new(|_value| {
304+
Box::pin(async { Err(FlowError::Internal("next failed".into())) })
305+
})),
306+
runtime: runtime.handle().clone(),
307+
});
308+
let next_ref = Arc::into_raw(next);
309+
let invocation = CString::new("{}").unwrap();
310+
let (sender, receiver) = tokio::sync::oneshot::channel::<std::result::Result<Json, String>>();
311+
assert_eq!(
312+
unsafe {
313+
nemo_relay_async_next_invoke_callback(
314+
next_ref,
315+
invocation.as_ptr(),
316+
send_next_result,
317+
Box::into_raw(Box::new(sender)).cast(),
318+
)
319+
},
320+
NemoRelayStatus::Ok
321+
);
322+
assert!(
323+
runtime
324+
.block_on(receiver)
325+
.unwrap()
326+
.unwrap_err()
327+
.contains("next failed")
328+
);
329+
unsafe { nemo_relay_async_next_release(next_ref) };
301330
}

0 commit comments

Comments
 (0)