This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new b4fc35660a fix(rust): return NotFound on driver not found instead of
Internal on Windows (#4971)
b4fc35660a is described below
commit b4fc35660a17a199ebef31ea4d6024d69445c91c
Author: Bryce Mecum <[email protected]>
AuthorDate: Tue Oct 27 21:13:51 2026 -0700
fix(rust): return NotFound on driver not found instead of Internal on
Windows (#4971)
The Rust driver manager returns an inconsistent error class across
platforms. On non-Windows platforms, trying to load a driver that
doesn't exist is handled and we return NotFound. On Windows, don't catch
a failed load and just pass it upwards which results in an Internal
error. I don't think there's any good reason to return different errors
for the same behavior across platforms.
There's a TODO about this:
https://github.com/apache/arrow-adbc/blob/main/rust/driver_manager/src/search.rs#L527.
This PR syncs the behavior between non-Windows and Windows platforms in
the Rust driver manager and adds a regression test in the Javascript
bindings. The new behavior is tested by updating the existing
`test_load_from_name_missing_driver` test to not only verify we return a
non-empty error but that we return a Driver not found error with detail.
---
javascript/__test__/error_handling.spec.ts | 12 ++++++++++++
rust/driver_manager/src/search.rs | 27 +++++++++++++++++++++------
2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/javascript/__test__/error_handling.spec.ts
b/javascript/__test__/error_handling.spec.ts
index 980099b206..61f1cabbe7 100644
--- a/javascript/__test__/error_handling.spec.ts
+++ b/javascript/__test__/error_handling.spec.ts
@@ -190,3 +190,15 @@ test('error: conn.queryStream() error during iteration
throws AdbcError', async
assert.ok(error instanceof AdbcError)
assert.match((error as AdbcError).message, /no such table/i)
})
+
+test('error: missing driver throws NotFound', () => {
+ assert.throws(
+ () => new AdbcDatabase({ driver:
'adbc_test_driver_manager_missing_driver_7c8f5482' }),
+ (e: unknown) => {
+ assert.ok(e instanceof AdbcError)
+ assert.strictEqual(e.code, 'NotFound', e.message)
+ assert.match(e.message, /Driver not found/)
+ return true
+ },
+ )
+})
diff --git a/rust/driver_manager/src/search.rs
b/rust/driver_manager/src/search.rs
index 9719a218bc..16aec91e3b 100644
--- a/rust/driver_manager/src/search.rs
+++ b/rust/driver_manager/src/search.rs
@@ -522,9 +522,15 @@ impl<'a> DriverLibrary<'a> {
}
let driver_name =
driver_path.as_os_str().to_string_lossy().into_owned();
- let library = DriverLibrary::load_library_from_name(driver_name)?;
- Ok(SearchHit::new(driver_path.to_path_buf(), library, None))
- // XXX: should we return NotFound like the non-Windows version?
+ match DriverLibrary::load_library_from_name(driver_name) {
+ Ok(library) => return Ok(SearchHit::new(driver_path.to_path_buf(),
library, None)),
+ Err(err) => trace.push(err),
+ }
+
+ Err(Error::with_message_and_status(
+ format!("Driver not found: {}", driver_path.display()),
+ Status::NotFound,
+ ))
}
#[cfg(not(windows))]
@@ -1652,7 +1658,7 @@ mod tests {
}
#[test]
- fn test_load_from_name_includes_search_trace_in_error_details() {
+ fn test_load_from_name_missing_driver() {
let err = ManagedDriver::load_from_name(
"adbc_test_driver_manager_missing_driver_7c8f5482",
None,
@@ -1662,6 +1668,13 @@ mod tests {
)
.unwrap_err();
+ assert_eq!(err.status, Status::NotFound, "{}", err.message);
+ assert!(
+ err.message.contains("Driver not found"),
+ "Unexpected error message: {}",
+ err.message
+ );
+
let details = err
.details
.expect("Expected load-from-name errors to include details");
@@ -1669,9 +1682,11 @@ mod tests {
.iter()
.find(|(key, _)| key == "adbc.drivermanager.driver_load_trace")
.expect("Expected driver load trace in error details");
+ // The underlying dynamic library error must be kept in the trace
+ let trace = String::from_utf8_lossy(&trace.1);
assert!(
- !trace.1.is_empty(),
- "Expected driver load trace detail to be non-empty"
+ trace.contains("Error with dynamic library"),
+ "Expected dynamic library load error in driver load trace,
got:\n{trace}"
);
}