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/call.rs | |
parent | 8dbe77dd29a3791db58fda392dea45d8249b6bc9 (diff) |
refactor(ext/ffi): use concrete error types (#26170)
Diffstat (limited to 'ext/ffi/call.rs')
-rw-r--r-- | ext/ffi/call.rs | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/ext/ffi/call.rs b/ext/ffi/call.rs index 3572b9e81..d337b29b0 100644 --- a/ext/ffi/call.rs +++ b/ext/ffi/call.rs @@ -7,9 +7,6 @@ use crate::symbol::NativeType; use crate::symbol::Symbol; use crate::FfiPermissions; use crate::ForeignFunction; -use deno_core::anyhow::anyhow; -use deno_core::error::type_error; -use deno_core::error::AnyError; use deno_core::op2; use deno_core::serde_json::Value; use deno_core::serde_v8::ExternalPointer; @@ -24,6 +21,20 @@ use std::ffi::c_void; use std::future::Future; use std::rc::Rc; +#[derive(Debug, thiserror::Error)] +pub enum CallError { + #[error(transparent)] + IR(#[from] IRError), + #[error("Nonblocking FFI call failed: {0}")] + NonblockingCallFailure(#[source] tokio::task::JoinError), + #[error("Invalid FFI symbol name: '{0}'")] + InvalidSymbol(String), + #[error(transparent)] + Permission(deno_core::error::AnyError), + #[error(transparent)] + Callback(#[from] super::CallbackError), +} + // SAFETY: Makes an FFI call unsafe fn ffi_call_rtype_struct( cif: &libffi::middle::Cif, @@ -45,7 +56,7 @@ pub(crate) fn ffi_call_sync<'scope>( args: v8::FunctionCallbackArguments, symbol: &Symbol, out_buffer: Option<OutBuffer>, -) -> Result<NativeValue, AnyError> +) -> Result<NativeValue, CallError> where 'scope: 'scope, { @@ -201,7 +212,7 @@ fn ffi_call( parameter_types: &[NativeType], result_type: NativeType, out_buffer: Option<OutBuffer>, -) -> Result<FfiValue, AnyError> { +) -> FfiValue { let call_args: Vec<Arg> = call_args .iter() .enumerate() @@ -214,7 +225,7 @@ fn ffi_call( // SAFETY: types in the `Cif` match the actual calling convention and // types of symbol. unsafe { - Ok(match result_type { + match result_type { NativeType::Void => { cif.call::<()>(fun_ptr, &call_args); FfiValue::Value(Value::from(())) @@ -267,7 +278,7 @@ fn ffi_call( ffi_call_rtype_struct(cif, &fun_ptr, call_args, out_buffer.unwrap().0); FfiValue::Value(Value::Null) } - }) + } } } @@ -280,14 +291,16 @@ pub fn op_ffi_call_ptr_nonblocking<FP>( #[serde] def: ForeignFunction, parameters: v8::Local<v8::Array>, out_buffer: Option<v8::Local<v8::TypedArray>>, -) -> Result<impl Future<Output = Result<FfiValue, AnyError>>, AnyError> +) -> Result<impl Future<Output = Result<FfiValue, CallError>>, CallError> where FP: FfiPermissions + 'static, { { let mut state = state.borrow_mut(); let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(CallError::Permission)?; }; let symbol = PtrSymbol::new(pointer, &def)?; @@ -309,7 +322,7 @@ where Ok(async move { let result = join_handle .await - .map_err(|err| anyhow!("Nonblocking FFI call failed: {}", err))??; + .map_err(CallError::NonblockingCallFailure)?; // SAFETY: Same return type declared to libffi; trust user to have it right beyond that. Ok(result) }) @@ -325,16 +338,17 @@ pub fn op_ffi_call_nonblocking( #[string] symbol: String, parameters: v8::Local<v8::Array>, out_buffer: Option<v8::Local<v8::TypedArray>>, -) -> Result<impl Future<Output = Result<FfiValue, AnyError>>, AnyError> { +) -> Result<impl Future<Output = Result<FfiValue, CallError>>, CallError> { let symbol = { let state = state.borrow(); - let resource = state.resource_table.get::<DynamicLibraryResource>(rid)?; + let resource = state + .resource_table + .get::<DynamicLibraryResource>(rid) + .map_err(CallError::Permission)?; let symbols = &resource.symbols; *symbols .get(&symbol) - .ok_or_else(|| { - type_error(format!("Invalid FFI symbol name: '{symbol}'")) - })? + .ok_or_else(|| CallError::InvalidSymbol(symbol))? .clone() }; @@ -362,7 +376,7 @@ pub fn op_ffi_call_nonblocking( Ok(async move { let result = join_handle .await - .map_err(|err| anyhow!("Nonblocking FFI call failed: {}", err))??; + .map_err(CallError::NonblockingCallFailure)?; // SAFETY: Same return type declared to libffi; trust user to have it right beyond that. Ok(result) }) @@ -377,14 +391,16 @@ pub fn op_ffi_call_ptr<FP>( #[serde] def: ForeignFunction, parameters: v8::Local<v8::Array>, out_buffer: Option<v8::Local<v8::TypedArray>>, -) -> Result<FfiValue, AnyError> +) -> Result<FfiValue, CallError> where FP: FfiPermissions + 'static, { { let mut state = state.borrow_mut(); let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(CallError::Permission)?; }; let symbol = PtrSymbol::new(pointer, &def)?; @@ -399,7 +415,7 @@ where &def.parameters, def.result.clone(), out_buffer_ptr, - )?; + ); // SAFETY: Same return type declared to libffi; trust user to have it right beyond that. Ok(result) } |