Skip to content

Comments

hmon: rework error handling in FFI#87

Open
arkjedrz wants to merge 1 commit intoeclipse-score:mainfrom
qorix-group:arkjedrz_ffi-return-codes
Open

hmon: rework error handling in FFI#87
arkjedrz wants to merge 1 commit intoeclipse-score:mainfrom
qorix-group:arkjedrz_ffi-return-codes

Conversation

@arkjedrz
Copy link
Contributor

@arkjedrz arkjedrz commented Feb 19, 2026

  • Uniformly return FFICode in FFI functions.
  • Unit tests for FFI functions in Rust.
  • Rework comments for FFI functions.
  • Move crate::common::ffi to crate::ffi.

Closes #82

@github-actions
Copy link

github-actions bot commented Feb 19, 2026

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.4.2) and connecting to it...
INFO: Invocation ID: 3bf6aa06-1dea-4526-a084-2f15dcc3bb41
Computing main repo mapping: 
Computing main repo mapping: 
WARNING: For repository 'rules_python', the root module requires module version rules_python@1.4.1, but got rules_python@1.8.3 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
WARNING: For repository 'rules_cc', the root module requires module version rules_cc@0.2.14, but got rules_cc@0.2.16 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
WARNING: For repository 'aspect_rules_lint', the root module requires module version aspect_rules_lint@1.5.3, but got aspect_rules_lint@2.0.0 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
WARNING: For repository 'download_utils', the root module requires module version download_utils@1.0.1, but got download_utils@1.2.2 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
WARNING: For repository 'googletest', the root module requires module version googletest@1.17.0.bcr.1, but got googletest@1.17.0.bcr.2 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
WARNING: For repository 'score_rust_policies', the root module requires module version score_rust_policies@0.0.3, but got score_rust_policies@0.0.5 in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Loading: 0 packages loaded
    currently loading: 
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)

Analyzing: target //:license-check (53 packages loaded, 9 targets configured)

Analyzing: target //:license-check (86 packages loaded, 9 targets configured)

Analyzing: target //:license-check (86 packages loaded, 9 targets configured)

Analyzing: target //:license-check (140 packages loaded, 2614 targets configured)

Analyzing: target //:license-check (148 packages loaded, 6336 targets configured)

Analyzing: target //:license-check (151 packages loaded, 7762 targets configured)

Analyzing: target //:license-check (151 packages loaded, 7762 targets configured)

Analyzing: target //:license-check (151 packages loaded, 7762 targets configured)

Analyzing: target //:license-check (160 packages loaded, 9897 targets configured)

Analyzing: target //:license-check (160 packages loaded, 9897 targets configured)

INFO: Analyzed target //:license-check (165 packages loaded, 9955 targets configured).
[12 / 16] JavaToolchainCompileClasses external/rules_java+/toolchains/platformclasspath_classes; 0s disk-cache, processwrapper-sandbox ... (2 actions, 1 running)
[14 / 16] JavaToolchainCompileBootClasspath external/rules_java+/toolchains/platformclasspath.jar; 0s disk-cache, processwrapper-sandbox
INFO: Found 1 target...
Target //:license.check.license_check up-to-date:
  bazel-bin/license.check.license_check
  bazel-bin/license.check.license_check.jar
INFO: Elapsed time: 30.301s, Critical Path: 2.70s
INFO: 16 processes: 12 internal, 3 processwrapper-sandbox, 1 worker.
INFO: Build completed successfully, 16 total actions
INFO: Running command line: bazel-bin/license.check.license_check ./formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@github-actions
Copy link

The created documentation from the pull request is available at: docu-html

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reworks the Health Monitoring (HMON) Rust↔C++ FFI surface to use a uniform return-code-based error model, updates the C++ wrappers to construct objects via factory methods returning expected, and adds Rust unit tests covering the FFI functions (in support of avoiding panics/terminates across extern "C" boundaries).

Changes:

  • Introduce a shared FFICode and convert Rust FFI functions to return it (with out-params for handles).
  • Update C++ wrappers/builders to use ::create() factory methods and expected<..., Error> for fallible construction/build.
  • Add/expand Rust unit tests for FFI functions and adjust the C++ tests to the new API.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
src/health_monitoring_lib/rust/lib.rs Documentation tweak for builder creation/build.
src/health_monitoring_lib/rust/ffi.rs New FFICode/FFIHandle, reworked HM FFI API + extensive Rust tests.
src/health_monitoring_lib/rust/deadline/ffi.rs Reworked deadline FFI API to FFICode + Rust tests.
src/health_monitoring_lib/rust/common.rs Removes old common::ffi module in favor of crate::ffi.
src/health_monitoring_lib/cpp/include/score/hm/common.h Introduces internal FFICode/kSuccess, updates Error codes & drop-fn signature.
src/health_monitoring_lib/cpp/include/score/hm/health_monitor.h Builder now uses create() + expected and build() becomes fallible.
src/health_monitoring_lib/cpp/include/score/hm/deadline/deadline_monitor.h Deadline builder now uses create() + expected.
src/health_monitoring_lib/cpp/health_monitor.cpp Implements new FFI signatures and expected-based factory/build paths.
src/health_monitoring_lib/cpp/deadline_monitor.cpp Implements new FFI signatures and expected-based factory paths.
src/health_monitoring_lib/cpp/tests/health_monitor_test.cpp Updates test to use create().value() and fallible build().value().
src/health_monitoring_lib/BUILD Removes deleted cpp/ffi_helpers.h from sources.
src/health_monitoring_lib/cpp/ffi_helpers.h Deleted legacy error mapping helper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 223 to 227
let mut health_monitor = FFIBorrowed::new(unsafe { Box::from_raw(health_monitor_handle as *mut HealthMonitor) });

health_monitor.start();

// Safety: We ensure that the pointer is valid. We assume that pointer was created by call to `health_monitor_builder_build`
// and this must be assured on other side of FFI.
let mut monitor = FFIBorrowed::new(unsafe { Box::from_raw(handle as *mut HealthMonitor) });
monitor.start();
FFICode::Success
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

health_monitor_start calls HealthMonitor::start(), which contains multiple assert!/panic! paths (e.g., no monitors, monitors not taken, invalid state). Any of these will abort when invoked through FFI. Pre-check the required invariants in this wrapper (and return FFICode::WrongState/InvalidArgument) or use catch_unwind so FFI callers can observe an error code instead of process termination.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. but when i read https://doc.rust-lang.org/std/panic/fn.catch_unwind.html extern "c" shall be ok . we can still catchunwind and abort on cpp side.

@arkjedrz arkjedrz force-pushed the arkjedrz_ffi-return-codes branch from f78336e to 507d936 Compare February 19, 2026 14:25
@arkjedrz arkjedrz temporarily deployed to workflow-approval February 19, 2026 14:25 — with GitHub Actions Inactive
@arkjedrz arkjedrz temporarily deployed to workflow-approval February 19, 2026 14:25 — with GitHub Actions Inactive
assert!(!handle.is_null());
assert!(!tag.is_null());
assert!(!monitor.is_null());
pub extern "C" fn health_monitor_builder_create(health_monitor_builder_handle: *mut FFIHandle) -> FFICode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why pub ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency and unit testing across ffi modules.
crate::deadline::ffi already had pub functions, and I need access to HMON functions from it to test it - otherwise deadline monitor cannot be obtained.
This shouldn't matter, as all ffi modules are crate-internal. I can replace pub with pub(crate) but this increases visual noise.

*deadline_handle = core::ptr::null_mut();
}
HM_OK
e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hard to spot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clarify.

@arkjedrz arkjedrz force-pushed the arkjedrz_ffi-return-codes branch from 507d936 to d179c88 Compare February 20, 2026 12:45
@arkjedrz arkjedrz temporarily deployed to workflow-approval February 20, 2026 12:45 — with GitHub Actions Inactive
@arkjedrz arkjedrz temporarily deployed to workflow-approval February 20, 2026 12:45 — with GitHub Actions Inactive
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/health_monitoring_lib/cpp/health_monitor.cpp:136

  • The destructor calls health_monitor_destroy but ignores the returned FFICode. While ignoring errors in destructors is sometimes acceptable, this inconsistency could mask issues. Consider using abort_on_error for consistency with other parts of the codebase, or explicitly document why errors are ignored in destructors.
HealthMonitor::~HealthMonitor()
{
    if (health_monitor_ != nullptr)
    {
        health_monitor_destroy(health_monitor_);
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

&deadline_monitor_tag as *const IdentTag,
deadline_monitor_builder_handle,
);
assert!(!deadline_monitor_builder_handle.is_null());
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect assertion: After health_monitor_builder_add_deadline_monitor succeeds, the deadline_monitor_builder_handle has been consumed (the pointer was unboxed and the builder was moved). Asserting that the handle is not null checks a dangling pointer value. This assertion should be removed as it doesn't test anything meaningful and could give false confidence.

Suggested change
assert!(!deadline_monitor_builder_handle.is_null());

Copilot uses AI. Check for mistakes.
@arkjedrz arkjedrz force-pushed the arkjedrz_ffi-return-codes branch from 4b2a346 to 6f0335a Compare February 20, 2026 13:19
@arkjedrz arkjedrz temporarily deployed to workflow-approval February 20, 2026 13:19 — with GitHub Actions Inactive
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 367 to 382
fn health_monitor_builder_add_deadline_monitor_null_hmon_builder() {
let mut deadline_monitor_builder_handle: FFIHandle = null_mut();

let deadline_monitor_tag = IdentTag::new("deadline_monitor");
let _ = deadline_monitor_builder_create(&mut deadline_monitor_builder_handle as *mut FFIHandle);

let health_monitor_builder_add_deadline_monitor_result = health_monitor_builder_add_deadline_monitor(
null_mut(),
&deadline_monitor_tag as *const IdentTag,
deadline_monitor_builder_handle,
);
assert_eq!(
health_monitor_builder_add_deadline_monitor_result,
FFICode::NullParameter
);
}
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deadline_monitor_builder_handle created at line 371 is never destroyed when the function returns FFICode::NullParameter. This causes a resource leak in the test. Add cleanup by calling deadline_monitor_builder_destroy(deadline_monitor_builder_handle) before the test ends.

Copilot uses AI. Check for mistakes.
@arkjedrz arkjedrz force-pushed the arkjedrz_ffi-return-codes branch from 6f0335a to 69fcbc8 Compare February 20, 2026 13:47
@arkjedrz arkjedrz temporarily deployed to workflow-approval February 20, 2026 13:47 — with GitHub Actions Inactive
@arkjedrz arkjedrz temporarily deployed to workflow-approval February 20, 2026 13:47 — with GitHub Actions Inactive
- Uniformly return `FFICode` in FFI functions.
- Unit tests for FFI functions in Rust.
- Rework comments for FFI functions.
- Move `crate::common::ffi` to `crate::ffi`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improvement: make FFI functions in HMON return error code

2 participants