summaryrefslogtreecommitdiff
path: root/ext/ffi/dlfcn.rs
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2024-10-14 15:05:49 -0700
committerGitHub <noreply@github.com>2024-10-14 15:05:49 -0700
commitee7d4501435f0ebd655c8b50bd6e41ca19e71abc (patch)
tree00b3fce4c8d36320f360000b4b22024f9935ad8e /ext/ffi/dlfcn.rs
parent8dbe77dd29a3791db58fda392dea45d8249b6bc9 (diff)
refactor(ext/ffi): use concrete error types (#26170)
Diffstat (limited to 'ext/ffi/dlfcn.rs')
-rw-r--r--ext/ffi/dlfcn.rs48
1 files changed, 34 insertions, 14 deletions
diff --git a/ext/ffi/dlfcn.rs b/ext/ffi/dlfcn.rs
index 10199bf85..53bdcbc5c 100644
--- a/ext/ffi/dlfcn.rs
+++ b/ext/ffi/dlfcn.rs
@@ -6,8 +6,6 @@ use crate::symbol::Symbol;
use crate::turbocall;
use crate::turbocall::Turbocall;
use crate::FfiPermissions;
-use deno_core::error::generic_error;
-use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::v8;
use deno_core::GarbageCollected;
@@ -21,6 +19,22 @@ use std::collections::HashMap;
use std::ffi::c_void;
use std::rc::Rc;
+#[derive(Debug, thiserror::Error)]
+pub enum DlfcnError {
+ #[error("Failed to register symbol {symbol}: {error}")]
+ RegisterSymbol {
+ symbol: String,
+ #[source]
+ error: dlopen2::Error,
+ },
+ #[error(transparent)]
+ Dlopen(#[from] dlopen2::Error),
+ #[error(transparent)]
+ Permission(deno_core::error::AnyError),
+ #[error(transparent)]
+ Other(deno_core::error::AnyError),
+}
+
pub struct DynamicLibraryResource {
lib: Library,
pub symbols: HashMap<String, Box<Symbol>>,
@@ -37,7 +51,7 @@ impl Resource for DynamicLibraryResource {
}
impl DynamicLibraryResource {
- pub fn get_static(&self, symbol: String) -> Result<*mut c_void, AnyError> {
+ pub fn get_static(&self, symbol: String) -> Result<*mut c_void, DlfcnError> {
// By default, Err returned by this function does not tell
// which symbol wasn't exported. So we'll modify the error
// message to include the name of symbol.
@@ -45,9 +59,7 @@ impl DynamicLibraryResource {
// SAFETY: The obtained T symbol is the size of a pointer.
match unsafe { self.lib.symbol::<*mut c_void>(&symbol) } {
Ok(value) => Ok(Ok(value)),
- Err(err) => Err(generic_error(format!(
- "Failed to register symbol {symbol}: {err}"
- ))),
+ Err(error) => Err(DlfcnError::RegisterSymbol { symbol, error }),
}?
}
}
@@ -116,12 +128,14 @@ pub fn op_ffi_load<'scope, FP>(
scope: &mut v8::HandleScope<'scope>,
state: &mut OpState,
#[serde] args: FfiLoadArgs,
-) -> Result<v8::Local<'scope, v8::Value>, AnyError>
+) -> Result<v8::Local<'scope, v8::Value>, DlfcnError>
where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- let path = permissions.check_partial_with_path(&args.path)?;
+ let path = permissions
+ .check_partial_with_path(&args.path)
+ .map_err(DlfcnError::Permission)?;
let lib = Library::open(&path).map_err(|e| {
dlopen2::Error::OpeningLibraryError(std::io::Error::new(
@@ -152,15 +166,16 @@ where
// SAFETY: The obtained T symbol is the size of a pointer.
match unsafe { resource.lib.symbol::<*const c_void>(symbol) } {
Ok(value) => Ok(value),
- Err(err) => if foreign_fn.optional {
+ Err(error) => if foreign_fn.optional {
let null: v8::Local<v8::Value> = v8::null(scope).into();
let func_key = v8::String::new(scope, &symbol_key).unwrap();
obj.set(scope, func_key.into(), null);
break 'register_symbol;
} else {
- Err(generic_error(format!(
- "Failed to register symbol {symbol}: {err}"
- )))
+ Err(DlfcnError::RegisterSymbol {
+ symbol: symbol.to_owned(),
+ error,
+ })
},
}?;
@@ -171,8 +186,13 @@ where
.clone()
.into_iter()
.map(libffi::middle::Type::try_from)
- .collect::<Result<Vec<_>, _>>()?,
- foreign_fn.result.clone().try_into()?,
+ .collect::<Result<Vec<_>, _>>()
+ .map_err(DlfcnError::Other)?,
+ foreign_fn
+ .result
+ .clone()
+ .try_into()
+ .map_err(DlfcnError::Other)?,
);
let func_key = v8::String::new(scope, &symbol_key).unwrap();