diff options
author | Leo Kettmeir <crowlkats@toaxl.com> | 2024-10-22 01:41:08 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-22 01:41:08 -0700 |
commit | f26c8bcf3167069ccd8ac3beb9185d1bf480a83f (patch) | |
tree | 6c83977b6d2e5b2cbfef9e8bde17188d5cc18347 /runtime/ops/os/mod.rs | |
parent | 67280f8b558902729c805fd3d8f26d4c434fc211 (diff) |
refactor(runtime/ops): use concrete error types (#26409)
Diffstat (limited to 'runtime/ops/os/mod.rs')
-rw-r--r-- | runtime/ops/os/mod.rs | 115 |
1 files changed, 78 insertions, 37 deletions
diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index bd9260e97..24b0389e1 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -1,9 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use super::utils::into_string; use crate::worker::ExitCode; -use deno_core::error::type_error; -use deno_core::error::AnyError; use deno_core::op2; use deno_core::v8; use deno_core::OpState; @@ -73,17 +70,39 @@ deno_core::extension!( }, ); +#[derive(Debug, thiserror::Error)] +pub enum OsError { + #[error(transparent)] + Permission(deno_core::error::AnyError), + #[error("File name or path {0:?} is not valid UTF-8")] + InvalidUtf8(std::ffi::OsString), + #[error("Key is an empty string.")] + EnvEmptyKey, + #[error("Key contains invalid characters: {0:?}")] + EnvInvalidKey(String), + #[error("Value contains invalid characters: {0:?}")] + EnvInvalidValue(String), + #[error(transparent)] + Var(#[from] env::VarError), + #[error("{0}")] + Io(#[from] std::io::Error), +} + #[op2] #[string] -fn op_exec_path(state: &mut OpState) -> Result<String, AnyError> { +fn op_exec_path(state: &mut OpState) -> Result<String, OsError> { let current_exe = env::current_exe().unwrap(); state .borrow_mut::<PermissionsContainer>() - .check_read_blind(¤t_exe, "exec_path", "Deno.execPath()")?; + .check_read_blind(¤t_exe, "exec_path", "Deno.execPath()") + .map_err(OsError::Permission)?; // normalize path so it doesn't include '.' or '..' components let path = normalize_path(current_exe); - into_string(path.into_os_string()) + path + .into_os_string() + .into_string() + .map_err(OsError::InvalidUtf8) } #[op2(fast)] @@ -91,20 +110,19 @@ fn op_set_env( state: &mut OpState, #[string] key: &str, #[string] value: &str, -) -> Result<(), AnyError> { - state.borrow_mut::<PermissionsContainer>().check_env(key)?; +) -> Result<(), OsError> { + state + .borrow_mut::<PermissionsContainer>() + .check_env(key) + .map_err(OsError::Permission)?; if key.is_empty() { - return Err(type_error("Key is an empty string.")); + return Err(OsError::EnvEmptyKey); } if key.contains(&['=', '\0'] as &[char]) { - return Err(type_error(format!( - "Key contains invalid characters: {key:?}" - ))); + return Err(OsError::EnvInvalidKey(key.to_string())); } if value.contains('\0') { - return Err(type_error(format!( - "Value contains invalid characters: {value:?}" - ))); + return Err(OsError::EnvInvalidValue(value.to_string())); } env::set_var(key, value); Ok(()) @@ -112,7 +130,9 @@ fn op_set_env( #[op2] #[serde] -fn op_env(state: &mut OpState) -> Result<HashMap<String, String>, AnyError> { +fn op_env( + state: &mut OpState, +) -> Result<HashMap<String, String>, deno_core::error::AnyError> { state.borrow_mut::<PermissionsContainer>().check_env_all()?; Ok(env::vars().collect()) } @@ -122,21 +142,22 @@ fn op_env(state: &mut OpState) -> Result<HashMap<String, String>, AnyError> { fn op_get_env( state: &mut OpState, #[string] key: String, -) -> Result<Option<String>, AnyError> { +) -> Result<Option<String>, OsError> { let skip_permission_check = NODE_ENV_VAR_ALLOWLIST.contains(&key); if !skip_permission_check { - state.borrow_mut::<PermissionsContainer>().check_env(&key)?; + state + .borrow_mut::<PermissionsContainer>() + .check_env(&key) + .map_err(OsError::Permission)?; } if key.is_empty() { - return Err(type_error("Key is an empty string.")); + return Err(OsError::EnvEmptyKey); } if key.contains(&['=', '\0'] as &[char]) { - return Err(type_error(format!( - "Key contains invalid characters: {key:?}" - ))); + return Err(OsError::EnvInvalidKey(key.to_string())); } let r = match env::var(key) { @@ -150,10 +171,13 @@ fn op_get_env( fn op_delete_env( state: &mut OpState, #[string] key: String, -) -> Result<(), AnyError> { - state.borrow_mut::<PermissionsContainer>().check_env(&key)?; +) -> Result<(), OsError> { + state + .borrow_mut::<PermissionsContainer>() + .check_env(&key) + .map_err(OsError::Permission)?; if key.is_empty() || key.contains(&['=', '\0'] as &[char]) { - return Err(type_error("Key contains invalid characters.")); + return Err(OsError::EnvInvalidKey(key.to_string())); } env::remove_var(key); Ok(()) @@ -178,7 +202,9 @@ fn op_exit(state: &mut OpState) { #[op2] #[serde] -fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> { +fn op_loadavg( + state: &mut OpState, +) -> Result<(f64, f64, f64), deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("loadavg", "Deno.loadavg()")?; @@ -187,7 +213,9 @@ fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> { #[op2] #[string] -fn op_hostname(state: &mut OpState) -> Result<String, AnyError> { +fn op_hostname( + state: &mut OpState, +) -> Result<String, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("hostname", "Deno.hostname()")?; @@ -196,7 +224,9 @@ fn op_hostname(state: &mut OpState) -> Result<String, AnyError> { #[op2] #[string] -fn op_os_release(state: &mut OpState) -> Result<String, AnyError> { +fn op_os_release( + state: &mut OpState, +) -> Result<String, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("osRelease", "Deno.osRelease()")?; @@ -207,10 +237,11 @@ fn op_os_release(state: &mut OpState) -> Result<String, AnyError> { #[serde] fn op_network_interfaces( state: &mut OpState, -) -> Result<Vec<NetworkInterface>, AnyError> { +) -> Result<Vec<NetworkInterface>, OsError> { state .borrow_mut::<PermissionsContainer>() - .check_sys("networkInterfaces", "Deno.networkInterfaces()")?; + .check_sys("networkInterfaces", "Deno.networkInterfaces()") + .map_err(OsError::Permission)?; Ok(netif::up()?.map(NetworkInterface::from).collect()) } @@ -259,7 +290,7 @@ impl From<netif::Interface> for NetworkInterface { #[serde] fn op_system_memory_info( state: &mut OpState, -) -> Result<Option<sys_info::MemInfo>, AnyError> { +) -> Result<Option<sys_info::MemInfo>, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("systemMemoryInfo", "Deno.systemMemoryInfo()")?; @@ -269,7 +300,9 @@ fn op_system_memory_info( #[cfg(not(windows))] #[op2] #[smi] -fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> { +fn op_gid( + state: &mut OpState, +) -> Result<Option<u32>, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("gid", "Deno.gid()")?; @@ -283,7 +316,9 @@ fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> { #[cfg(windows)] #[op2] #[smi] -fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> { +fn op_gid( + state: &mut OpState, +) -> Result<Option<u32>, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("gid", "Deno.gid()")?; @@ -293,7 +328,9 @@ fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> { #[cfg(not(windows))] #[op2] #[smi] -fn op_uid(state: &mut OpState) -> Result<Option<u32>, AnyError> { +fn op_uid( + state: &mut OpState, +) -> Result<Option<u32>, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("uid", "Deno.uid()")?; @@ -307,7 +344,9 @@ fn op_uid(state: &mut OpState) -> Result<Option<u32>, AnyError> { #[cfg(windows)] #[op2] #[smi] -fn op_uid(state: &mut OpState) -> Result<Option<u32>, AnyError> { +fn op_uid( + state: &mut OpState, +) -> Result<Option<u32>, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("uid", "Deno.uid()")?; @@ -485,7 +524,7 @@ fn rss() -> usize { } } -fn os_uptime(state: &mut OpState) -> Result<u64, AnyError> { +fn os_uptime(state: &mut OpState) -> Result<u64, deno_core::error::AnyError> { state .borrow_mut::<PermissionsContainer>() .check_sys("osUptime", "Deno.osUptime()")?; @@ -494,6 +533,8 @@ fn os_uptime(state: &mut OpState) -> Result<u64, AnyError> { #[op2(fast)] #[number] -fn op_os_uptime(state: &mut OpState) -> Result<u64, AnyError> { +fn op_os_uptime( + state: &mut OpState, +) -> Result<u64, deno_core::error::AnyError> { os_uptime(state) } |