diff options
author | Leo Kettmeir <crowlkats@toaxl.com> | 2024-10-14 15:05:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-14 15:05:49 -0700 |
commit | ee7d4501435f0ebd655c8b50bd6e41ca19e71abc (patch) | |
tree | 00b3fce4c8d36320f360000b4b22024f9935ad8e /ext/ffi/dlfcn.rs | |
parent | 8dbe77dd29a3791db58fda392dea45d8249b6bc9 (diff) |
refactor(ext/ffi): use concrete error types (#26170)
Diffstat (limited to 'ext/ffi/dlfcn.rs')
-rw-r--r-- | ext/ffi/dlfcn.rs | 48 |
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(); |