mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
refactor(ext/node): use concrete error types (#26419)
This commit is contained in:
parent
d68c5b9a46
commit
f62283f0c4
18 changed files with 674 additions and 305 deletions
30
ext/io/fs.rs
30
ext/io/fs.rs
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Formatter;
|
||||
use std::io;
|
||||
use std::rc::Rc;
|
||||
use std::time::SystemTime;
|
||||
|
@ -21,6 +22,21 @@ pub enum FsError {
|
|||
NotCapable(&'static str),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for FsError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
FsError::Io(err) => std::fmt::Display::fmt(err, f),
|
||||
FsError::FileBusy => f.write_str("file busy"),
|
||||
FsError::NotSupported => f.write_str("not supported"),
|
||||
FsError::NotCapable(err) => {
|
||||
f.write_str(&format!("requires {err} access"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for FsError {}
|
||||
|
||||
impl FsError {
|
||||
pub fn kind(&self) -> io::ErrorKind {
|
||||
match self {
|
||||
|
@ -55,20 +71,6 @@ impl From<io::ErrorKind> for FsError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<FsError> for deno_core::error::AnyError {
|
||||
fn from(err: FsError) -> Self {
|
||||
match err {
|
||||
FsError::Io(err) => err.into(),
|
||||
FsError::FileBusy => deno_core::error::resource_unavailable(),
|
||||
FsError::NotSupported => deno_core::error::not_supported(),
|
||||
FsError::NotCapable(err) => deno_core::error::custom_error(
|
||||
"NotCapable",
|
||||
format!("permission denied: {err}"),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<JoinError> for FsError {
|
||||
fn from(err: JoinError) -> Self {
|
||||
if err.is_cancelled() {
|
||||
|
|
|
@ -24,7 +24,7 @@ use once_cell::sync::Lazy;
|
|||
extern crate libz_sys as zlib;
|
||||
|
||||
mod global;
|
||||
mod ops;
|
||||
pub mod ops;
|
||||
mod polyfill;
|
||||
|
||||
pub use deno_package_json::PackageJson;
|
||||
|
|
|
@ -7,9 +7,6 @@ use std::net::Ipv4Addr;
|
|||
use std::net::Ipv6Addr;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
|
||||
|
@ -27,13 +24,25 @@ impl deno_core::GarbageCollected for BlockListResource {}
|
|||
#[derive(Serialize)]
|
||||
struct SocketAddressSerialization(String, String);
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum BlocklistError {
|
||||
#[error("{0}")]
|
||||
AddrParse(#[from] std::net::AddrParseError),
|
||||
#[error("{0}")]
|
||||
IpNetwork(#[from] ipnetwork::IpNetworkError),
|
||||
#[error("Invalid address")]
|
||||
InvalidAddress,
|
||||
#[error("IP version mismatch between start and end addresses")]
|
||||
IpVersionMismatch,
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_socket_address_parse(
|
||||
state: &mut OpState,
|
||||
#[string] addr: &str,
|
||||
#[smi] port: u16,
|
||||
#[string] family: &str,
|
||||
) -> Result<bool, AnyError> {
|
||||
) -> Result<bool, BlocklistError> {
|
||||
let ip = addr.parse::<IpAddr>()?;
|
||||
let parsed: SocketAddr = SocketAddr::new(ip, port);
|
||||
let parsed_ip_str = parsed.ip().to_string();
|
||||
|
@ -52,7 +61,7 @@ pub fn op_socket_address_parse(
|
|||
Ok(false)
|
||||
}
|
||||
} else {
|
||||
Err(anyhow!("Invalid address"))
|
||||
Err(BlocklistError::InvalidAddress)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,8 +69,8 @@ pub fn op_socket_address_parse(
|
|||
#[serde]
|
||||
pub fn op_socket_address_get_serialization(
|
||||
state: &mut OpState,
|
||||
) -> Result<SocketAddressSerialization, AnyError> {
|
||||
Ok(state.take::<SocketAddressSerialization>())
|
||||
) -> SocketAddressSerialization {
|
||||
state.take::<SocketAddressSerialization>()
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
@ -77,7 +86,7 @@ pub fn op_blocklist_new() -> BlockListResource {
|
|||
pub fn op_blocklist_add_address(
|
||||
#[cppgc] wrap: &BlockListResource,
|
||||
#[string] addr: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BlocklistError> {
|
||||
wrap.blocklist.borrow_mut().add_address(addr)
|
||||
}
|
||||
|
||||
|
@ -86,7 +95,7 @@ pub fn op_blocklist_add_range(
|
|||
#[cppgc] wrap: &BlockListResource,
|
||||
#[string] start: &str,
|
||||
#[string] end: &str,
|
||||
) -> Result<bool, AnyError> {
|
||||
) -> Result<bool, BlocklistError> {
|
||||
wrap.blocklist.borrow_mut().add_range(start, end)
|
||||
}
|
||||
|
||||
|
@ -95,7 +104,7 @@ pub fn op_blocklist_add_subnet(
|
|||
#[cppgc] wrap: &BlockListResource,
|
||||
#[string] addr: &str,
|
||||
#[smi] prefix: u8,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BlocklistError> {
|
||||
wrap.blocklist.borrow_mut().add_subnet(addr, prefix)
|
||||
}
|
||||
|
||||
|
@ -104,7 +113,7 @@ pub fn op_blocklist_check(
|
|||
#[cppgc] wrap: &BlockListResource,
|
||||
#[string] addr: &str,
|
||||
#[string] r#type: &str,
|
||||
) -> Result<bool, AnyError> {
|
||||
) -> Result<bool, BlocklistError> {
|
||||
wrap.blocklist.borrow().check(addr, r#type)
|
||||
}
|
||||
|
||||
|
@ -123,7 +132,7 @@ impl BlockList {
|
|||
&mut self,
|
||||
addr: IpAddr,
|
||||
prefix: Option<u8>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BlocklistError> {
|
||||
match addr {
|
||||
IpAddr::V4(addr) => {
|
||||
let ipv4_prefix = prefix.unwrap_or(32);
|
||||
|
@ -154,7 +163,7 @@ impl BlockList {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_address(&mut self, address: &str) -> Result<(), AnyError> {
|
||||
pub fn add_address(&mut self, address: &str) -> Result<(), BlocklistError> {
|
||||
let ip: IpAddr = address.parse()?;
|
||||
self.map_addr_add_network(ip, None)?;
|
||||
Ok(())
|
||||
|
@ -164,7 +173,7 @@ impl BlockList {
|
|||
&mut self,
|
||||
start: &str,
|
||||
end: &str,
|
||||
) -> Result<bool, AnyError> {
|
||||
) -> Result<bool, BlocklistError> {
|
||||
let start_ip: IpAddr = start.parse()?;
|
||||
let end_ip: IpAddr = end.parse()?;
|
||||
|
||||
|
@ -193,25 +202,33 @@ impl BlockList {
|
|||
self.map_addr_add_network(IpAddr::V6(addr), None)?;
|
||||
}
|
||||
}
|
||||
_ => bail!("IP version mismatch between start and end addresses"),
|
||||
_ => return Err(BlocklistError::IpVersionMismatch),
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn add_subnet(&mut self, addr: &str, prefix: u8) -> Result<(), AnyError> {
|
||||
pub fn add_subnet(
|
||||
&mut self,
|
||||
addr: &str,
|
||||
prefix: u8,
|
||||
) -> Result<(), BlocklistError> {
|
||||
let ip: IpAddr = addr.parse()?;
|
||||
self.map_addr_add_network(ip, Some(prefix))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check(&self, addr: &str, r#type: &str) -> Result<bool, AnyError> {
|
||||
pub fn check(
|
||||
&self,
|
||||
addr: &str,
|
||||
r#type: &str,
|
||||
) -> Result<bool, BlocklistError> {
|
||||
let addr: IpAddr = addr.parse()?;
|
||||
let family = r#type.to_lowercase();
|
||||
if family == "ipv4" && addr.is_ipv4() || family == "ipv6" && addr.is_ipv6()
|
||||
{
|
||||
Ok(self.rules.iter().any(|net| net.contains(addr)))
|
||||
} else {
|
||||
Err(anyhow!("Invalid address"))
|
||||
Err(BlocklistError::InvalidAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_fs::FileSystemRc;
|
||||
|
@ -11,11 +10,27 @@ use serde::Serialize;
|
|||
|
||||
use crate::NodePermissions;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum FsError {
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
#[error("{0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[cfg(windows)]
|
||||
#[error("Path has no root.")]
|
||||
PathHasNoRoot,
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
#[error("Unsupported platform.")]
|
||||
UnsupportedPlatform,
|
||||
#[error(transparent)]
|
||||
Fs(#[from] deno_io::fs::FsError),
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_node_fs_exists_sync<P>(
|
||||
state: &mut OpState,
|
||||
#[string] path: String,
|
||||
) -> Result<bool, AnyError>
|
||||
) -> Result<bool, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -30,7 +45,7 @@ where
|
|||
pub async fn op_node_fs_exists<P>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[string] path: String,
|
||||
) -> Result<bool, AnyError>
|
||||
) -> Result<bool, FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -38,7 +53,8 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(&path, Some("node:fs.exists()"))?;
|
||||
.check_read_with_api_name(&path, Some("node:fs.exists()"))
|
||||
.map_err(FsError::Permission)?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -50,16 +66,18 @@ pub fn op_node_cp_sync<P>(
|
|||
state: &mut OpState,
|
||||
#[string] path: &str,
|
||||
#[string] new_path: &str,
|
||||
) -> Result<(), AnyError>
|
||||
) -> Result<(), FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(path, Some("node:fs.cpSync"))?;
|
||||
.check_read_with_api_name(path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
let new_path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(new_path, Some("node:fs.cpSync"))?;
|
||||
.check_write_with_api_name(new_path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.cp_sync(&path, &new_path)?;
|
||||
|
@ -71,7 +89,7 @@ pub async fn op_node_cp<P>(
|
|||
state: Rc<RefCell<OpState>>,
|
||||
#[string] path: String,
|
||||
#[string] new_path: String,
|
||||
) -> Result<(), AnyError>
|
||||
) -> Result<(), FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -79,10 +97,12 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(&path, Some("node:fs.cpSync"))?;
|
||||
.check_read_with_api_name(&path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
let new_path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&new_path, Some("node:fs.cpSync"))?;
|
||||
.check_write_with_api_name(&new_path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path, new_path)
|
||||
};
|
||||
|
||||
|
@ -108,7 +128,7 @@ pub fn op_node_statfs<P>(
|
|||
state: Rc<RefCell<OpState>>,
|
||||
#[string] path: String,
|
||||
bigint: bool,
|
||||
) -> Result<StatFs, AnyError>
|
||||
) -> Result<StatFs, FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -116,10 +136,12 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(&path, Some("node:fs.statfs"))?;
|
||||
.check_read_with_api_name(&path, Some("node:fs.statfs"))
|
||||
.map_err(FsError::Permission)?;
|
||||
state
|
||||
.borrow_mut::<P>()
|
||||
.check_sys("statfs", "node:fs.statfs")?;
|
||||
.check_sys("statfs", "node:fs.statfs")
|
||||
.map_err(FsError::Permission)?;
|
||||
path
|
||||
};
|
||||
#[cfg(unix)]
|
||||
|
@ -176,7 +198,6 @@ where
|
|||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use deno_core::anyhow::anyhow;
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use windows_sys::Win32::Storage::FileSystem::GetDiskFreeSpaceW;
|
||||
|
@ -186,10 +207,7 @@ where
|
|||
// call below.
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let path = path.canonicalize()?;
|
||||
let root = path
|
||||
.ancestors()
|
||||
.last()
|
||||
.ok_or(anyhow!("Path has no root."))?;
|
||||
let root = path.ancestors().last().ok_or(FsError::PathHasNoRoot)?;
|
||||
let mut root = OsStr::new(root).encode_wide().collect::<Vec<_>>();
|
||||
root.push(0);
|
||||
let mut sectors_per_cluster = 0;
|
||||
|
@ -229,7 +247,7 @@ where
|
|||
{
|
||||
let _ = path;
|
||||
let _ = bigint;
|
||||
Err(anyhow!("Unsupported platform."))
|
||||
Err(FsError::UnsupportedPlatform)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,13 +259,14 @@ pub fn op_node_lutimes_sync<P>(
|
|||
#[smi] atime_nanos: u32,
|
||||
#[number] mtime_secs: i64,
|
||||
#[smi] mtime_nanos: u32,
|
||||
) -> Result<(), AnyError>
|
||||
) -> Result<(), FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(path, Some("node:fs.lutimes"))?;
|
||||
.check_write_with_api_name(path, Some("node:fs.lutimes"))
|
||||
.map_err(FsError::Permission)?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.lutime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos)?;
|
||||
|
@ -262,7 +281,7 @@ pub async fn op_node_lutimes<P>(
|
|||
#[smi] atime_nanos: u32,
|
||||
#[number] mtime_secs: i64,
|
||||
#[smi] mtime_nanos: u32,
|
||||
) -> Result<(), AnyError>
|
||||
) -> Result<(), FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -270,7 +289,8 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&path, Some("node:fs.lutimesSync"))?;
|
||||
.check_write_with_api_name(&path, Some("node:fs.lutimesSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -286,13 +306,14 @@ pub fn op_node_lchown_sync<P>(
|
|||
#[string] path: String,
|
||||
uid: Option<u32>,
|
||||
gid: Option<u32>,
|
||||
) -> Result<(), AnyError>
|
||||
) -> Result<(), FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchownSync"))?;
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchownSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.lchown_sync(&path, uid, gid)?;
|
||||
Ok(())
|
||||
|
@ -304,7 +325,7 @@ pub async fn op_node_lchown<P>(
|
|||
#[string] path: String,
|
||||
uid: Option<u32>,
|
||||
gid: Option<u32>,
|
||||
) -> Result<(), AnyError>
|
||||
) -> Result<(), FsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -312,7 +333,8 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchown"))?;
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchown"))
|
||||
.map_err(FsError::Permission)?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
fs.lchown_async(path, uid, gid).await?;
|
||||
|
|
|
@ -7,7 +7,6 @@ use std::rc::Rc;
|
|||
use std::task::Poll;
|
||||
|
||||
use bytes::Bytes;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future::poll_fn;
|
||||
use deno_core::op2;
|
||||
use deno_core::serde::Serialize;
|
||||
|
@ -110,17 +109,28 @@ impl Resource for Http2ServerSendResponse {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Http2Error {
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
UrlParse(#[from] url::ParseError),
|
||||
#[error(transparent)]
|
||||
H2(#[from] h2::Error),
|
||||
}
|
||||
|
||||
#[op2(async)]
|
||||
#[serde]
|
||||
pub async fn op_http2_connect(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
#[string] url: String,
|
||||
) -> Result<(ResourceId, ResourceId), AnyError> {
|
||||
) -> Result<(ResourceId, ResourceId), Http2Error> {
|
||||
// No permission check necessary because we're using an existing connection
|
||||
let network_stream = {
|
||||
let mut state = state.borrow_mut();
|
||||
take_network_stream_resource(&mut state.resource_table, rid)?
|
||||
take_network_stream_resource(&mut state.resource_table, rid)
|
||||
.map_err(Http2Error::Resource)?
|
||||
};
|
||||
|
||||
let url = Url::parse(&url)?;
|
||||
|
@ -144,9 +154,10 @@ pub async fn op_http2_connect(
|
|||
pub async fn op_http2_listen(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<ResourceId, AnyError> {
|
||||
) -> Result<ResourceId, Http2Error> {
|
||||
let stream =
|
||||
take_network_stream_resource(&mut state.borrow_mut().resource_table, rid)?;
|
||||
take_network_stream_resource(&mut state.borrow_mut().resource_table, rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
|
||||
let conn = h2::server::Builder::new().handshake(stream).await?;
|
||||
Ok(
|
||||
|
@ -166,12 +177,13 @@ pub async fn op_http2_accept(
|
|||
#[smi] rid: ResourceId,
|
||||
) -> Result<
|
||||
Option<(Vec<(ByteString, ByteString)>, ResourceId, ResourceId)>,
|
||||
AnyError,
|
||||
Http2Error,
|
||||
> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2ServerConnection>(rid)?;
|
||||
.get::<Http2ServerConnection>(rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
let mut conn = RcRef::map(&resource, |r| &r.conn).borrow_mut().await;
|
||||
if let Some(res) = conn.accept().await {
|
||||
let (req, resp) = res?;
|
||||
|
@ -233,11 +245,12 @@ pub async fn op_http2_send_response(
|
|||
#[smi] rid: ResourceId,
|
||||
#[smi] status: u16,
|
||||
#[serde] headers: Vec<(ByteString, ByteString)>,
|
||||
) -> Result<(ResourceId, u32), AnyError> {
|
||||
) -> Result<(ResourceId, u32), Http2Error> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2ServerSendResponse>(rid)?;
|
||||
.get::<Http2ServerSendResponse>(rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
let mut send_response = RcRef::map(resource, |r| &r.send_response)
|
||||
.borrow_mut()
|
||||
.await;
|
||||
|
@ -262,8 +275,12 @@ pub async fn op_http2_send_response(
|
|||
pub async fn op_http2_poll_client_connection(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<(), AnyError> {
|
||||
let resource = state.borrow().resource_table.get::<Http2ClientConn>(rid)?;
|
||||
) -> Result<(), Http2Error> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2ClientConn>(rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
|
||||
let cancel_handle = RcRef::map(resource.clone(), |this| &this.cancel_handle);
|
||||
let mut conn = RcRef::map(resource, |this| &this.conn).borrow_mut().await;
|
||||
|
@ -289,11 +306,12 @@ pub async fn op_http2_client_request(
|
|||
// 4 strings of keys?
|
||||
#[serde] mut pseudo_headers: HashMap<String, String>,
|
||||
#[serde] headers: Vec<(ByteString, ByteString)>,
|
||||
) -> Result<(ResourceId, u32), AnyError> {
|
||||
) -> Result<(ResourceId, u32), Http2Error> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2Client>(client_rid)?;
|
||||
.get::<Http2Client>(client_rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
|
||||
let url = resource.url.clone();
|
||||
|
||||
|
@ -326,7 +344,10 @@ pub async fn op_http2_client_request(
|
|||
|
||||
let resource = {
|
||||
let state = state.borrow();
|
||||
state.resource_table.get::<Http2Client>(client_rid)?
|
||||
state
|
||||
.resource_table
|
||||
.get::<Http2Client>(client_rid)
|
||||
.map_err(Http2Error::Resource)?
|
||||
};
|
||||
let mut client = RcRef::map(&resource, |r| &r.client).borrow_mut().await;
|
||||
poll_fn(|cx| client.poll_ready(cx)).await?;
|
||||
|
@ -345,11 +366,12 @@ pub async fn op_http2_client_send_data(
|
|||
#[smi] stream_rid: ResourceId,
|
||||
#[buffer] data: JsBuffer,
|
||||
end_of_stream: bool,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), Http2Error> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2ClientStream>(stream_rid)?;
|
||||
.get::<Http2ClientStream>(stream_rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
let mut stream = RcRef::map(&resource, |r| &r.stream).borrow_mut().await;
|
||||
|
||||
stream.send_data(data.to_vec().into(), end_of_stream)?;
|
||||
|
@ -361,7 +383,7 @@ pub async fn op_http2_client_reset_stream(
|
|||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] stream_rid: ResourceId,
|
||||
#[smi] code: u32,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
|
@ -376,11 +398,12 @@ pub async fn op_http2_client_send_trailers(
|
|||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] stream_rid: ResourceId,
|
||||
#[serde] trailers: Vec<(ByteString, ByteString)>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), Http2Error> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2ClientStream>(stream_rid)?;
|
||||
.get::<Http2ClientStream>(stream_rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
let mut stream = RcRef::map(&resource, |r| &r.stream).borrow_mut().await;
|
||||
|
||||
let mut trailers_map = http::HeaderMap::new();
|
||||
|
@ -408,11 +431,12 @@ pub struct Http2ClientResponse {
|
|||
pub async fn op_http2_client_get_response(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] stream_rid: ResourceId,
|
||||
) -> Result<(Http2ClientResponse, bool), AnyError> {
|
||||
) -> Result<(Http2ClientResponse, bool), Http2Error> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2ClientStream>(stream_rid)?;
|
||||
.get::<Http2ClientStream>(stream_rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
let mut response_future =
|
||||
RcRef::map(&resource, |r| &r.response).borrow_mut().await;
|
||||
|
||||
|
@ -478,11 +502,12 @@ fn poll_data_or_trailers(
|
|||
pub async fn op_http2_client_get_response_body_chunk(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] body_rid: ResourceId,
|
||||
) -> Result<(Option<Vec<u8>>, bool, bool), AnyError> {
|
||||
) -> Result<(Option<Vec<u8>>, bool, bool), Http2Error> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<Http2ClientResponseBody>(body_rid)?;
|
||||
.get::<Http2ClientResponseBody>(body_rid)
|
||||
.map_err(Http2Error::Resource)?;
|
||||
let mut body = RcRef::map(&resource, |r| &r.body).borrow_mut().await;
|
||||
|
||||
loop {
|
||||
|
@ -525,7 +550,7 @@ pub async fn op_http2_client_get_response_body_chunk(
|
|||
pub async fn op_http2_client_get_response_trailers(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] body_rid: ResourceId,
|
||||
) -> Result<Option<Vec<(ByteString, ByteString)>>, AnyError> {
|
||||
) -> Result<Option<Vec<(ByteString, ByteString)>>, deno_core::error::AnyError> {
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::anyhow::Error;
|
||||
use deno_core::error::range_error;
|
||||
use deno_core::op2;
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
@ -11,19 +9,21 @@ use std::borrow::Cow;
|
|||
|
||||
const PUNY_PREFIX: &str = "xn--";
|
||||
|
||||
fn invalid_input_err() -> Error {
|
||||
range_error("Invalid input")
|
||||
}
|
||||
|
||||
fn not_basic_err() -> Error {
|
||||
range_error("Illegal input >= 0x80 (not a basic code point)")
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum IdnaError {
|
||||
#[error("Invalid input")]
|
||||
InvalidInput,
|
||||
#[error("Input would take more than 63 characters to encode")]
|
||||
InputTooLong,
|
||||
#[error("Illegal input >= 0x80 (not a basic code point)")]
|
||||
IllegalInput,
|
||||
}
|
||||
|
||||
/// map a domain by mapping each label with the given function
|
||||
fn map_domain<E>(
|
||||
fn map_domain(
|
||||
domain: &str,
|
||||
f: impl Fn(&str) -> Result<Cow<'_, str>, E>,
|
||||
) -> Result<String, E> {
|
||||
f: impl Fn(&str) -> Result<Cow<'_, str>, IdnaError>,
|
||||
) -> Result<String, IdnaError> {
|
||||
let mut result = String::with_capacity(domain.len());
|
||||
let mut domain = domain;
|
||||
|
||||
|
@ -48,7 +48,7 @@ fn map_domain<E>(
|
|||
/// Maps a unicode domain to ascii by punycode encoding each label
|
||||
///
|
||||
/// Note this is not IDNA2003 or IDNA2008 compliant, rather it matches node.js's punycode implementation
|
||||
fn to_ascii(input: &str) -> Result<String, Error> {
|
||||
fn to_ascii(input: &str) -> Result<String, IdnaError> {
|
||||
if input.is_ascii() {
|
||||
return Ok(input.into());
|
||||
}
|
||||
|
@ -61,9 +61,7 @@ fn to_ascii(input: &str) -> Result<String, Error> {
|
|||
} else {
|
||||
idna::punycode::encode_str(label)
|
||||
.map(|encoded| [PUNY_PREFIX, &encoded].join("").into()) // add the prefix
|
||||
.ok_or_else(|| {
|
||||
Error::msg("Input would take more than 63 characters to encode") // only error possible per the docs
|
||||
})
|
||||
.ok_or(IdnaError::InputTooLong) // only error possible per the docs
|
||||
}
|
||||
})?;
|
||||
|
||||
|
@ -74,13 +72,13 @@ fn to_ascii(input: &str) -> Result<String, Error> {
|
|||
/// Maps an ascii domain to unicode by punycode decoding each label
|
||||
///
|
||||
/// Note this is not IDNA2003 or IDNA2008 compliant, rather it matches node.js's punycode implementation
|
||||
fn to_unicode(input: &str) -> Result<String, Error> {
|
||||
fn to_unicode(input: &str) -> Result<String, IdnaError> {
|
||||
map_domain(input, |s| {
|
||||
if let Some(puny) = s.strip_prefix(PUNY_PREFIX) {
|
||||
// it's a punycode encoded label
|
||||
Ok(
|
||||
idna::punycode::decode_to_string(&puny.to_lowercase())
|
||||
.ok_or_else(invalid_input_err)?
|
||||
.ok_or(IdnaError::InvalidInput)?
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
|
@ -95,7 +93,7 @@ fn to_unicode(input: &str) -> Result<String, Error> {
|
|||
#[string]
|
||||
pub fn op_node_idna_punycode_to_ascii(
|
||||
#[string] domain: String,
|
||||
) -> Result<String, Error> {
|
||||
) -> Result<String, IdnaError> {
|
||||
to_ascii(&domain)
|
||||
}
|
||||
|
||||
|
@ -105,7 +103,7 @@ pub fn op_node_idna_punycode_to_ascii(
|
|||
#[string]
|
||||
pub fn op_node_idna_punycode_to_unicode(
|
||||
#[string] domain: String,
|
||||
) -> Result<String, Error> {
|
||||
) -> Result<String, IdnaError> {
|
||||
to_unicode(&domain)
|
||||
}
|
||||
|
||||
|
@ -115,8 +113,8 @@ pub fn op_node_idna_punycode_to_unicode(
|
|||
#[string]
|
||||
pub fn op_node_idna_domain_to_ascii(
|
||||
#[string] domain: String,
|
||||
) -> Result<String, Error> {
|
||||
idna::domain_to_ascii(&domain).map_err(|e| e.into())
|
||||
) -> Result<String, idna::Errors> {
|
||||
idna::domain_to_ascii(&domain)
|
||||
}
|
||||
|
||||
/// Converts a domain to Unicode as per the IDNA spec
|
||||
|
@ -131,7 +129,7 @@ pub fn op_node_idna_domain_to_unicode(#[string] domain: String) -> String {
|
|||
#[string]
|
||||
pub fn op_node_idna_punycode_decode(
|
||||
#[string] domain: String,
|
||||
) -> Result<String, Error> {
|
||||
) -> Result<String, IdnaError> {
|
||||
if domain.is_empty() {
|
||||
return Ok(domain);
|
||||
}
|
||||
|
@ -147,11 +145,10 @@ pub fn op_node_idna_punycode_decode(
|
|||
.unwrap_or(domain.len() - 1);
|
||||
|
||||
if !domain[..last_dash].is_ascii() {
|
||||
return Err(not_basic_err());
|
||||
return Err(IdnaError::IllegalInput);
|
||||
}
|
||||
|
||||
idna::punycode::decode_to_string(&domain)
|
||||
.ok_or_else(|| deno_core::error::range_error("Invalid input"))
|
||||
idna::punycode::decode_to_string(&domain).ok_or(IdnaError::InvalidInput)
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
|
|
@ -17,8 +17,6 @@ mod impl_ {
|
|||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
use deno_core::error::bad_resource_id;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::serde;
|
||||
use deno_core::serde::Serializer;
|
||||
|
@ -167,7 +165,7 @@ mod impl_ {
|
|||
#[smi]
|
||||
pub fn op_node_child_ipc_pipe(
|
||||
state: &mut OpState,
|
||||
) -> Result<Option<ResourceId>, AnyError> {
|
||||
) -> Result<Option<ResourceId>, io::Error> {
|
||||
let fd = match state.try_borrow_mut::<crate::ChildPipeFd>() {
|
||||
Some(child_pipe_fd) => child_pipe_fd.0,
|
||||
None => return Ok(None),
|
||||
|
@ -180,6 +178,18 @@ mod impl_ {
|
|||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum IpcError {
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
IpcJsonStream(#[from] IpcJsonStreamError),
|
||||
#[error(transparent)]
|
||||
Canceled(#[from] deno_core::Canceled),
|
||||
#[error("failed to serialize json value: {0}")]
|
||||
SerdeJson(serde_json::Error),
|
||||
}
|
||||
|
||||
#[op2(async)]
|
||||
pub fn op_node_ipc_write<'a>(
|
||||
scope: &mut v8::HandleScope<'a>,
|
||||
|
@ -192,27 +202,23 @@ mod impl_ {
|
|||
// ideally we would just return `Result<(impl Future, bool), ..>`, but that's not
|
||||
// supported by `op2` currently.
|
||||
queue_ok: v8::Local<'a, v8::Array>,
|
||||
) -> Result<impl Future<Output = Result<(), AnyError>>, AnyError> {
|
||||
) -> Result<impl Future<Output = Result<(), io::Error>>, IpcError> {
|
||||
let mut serialized = Vec::with_capacity(64);
|
||||
let mut ser = serde_json::Serializer::new(&mut serialized);
|
||||
serialize_v8_value(scope, value, &mut ser).map_err(|e| {
|
||||
deno_core::error::type_error(format!(
|
||||
"failed to serialize json value: {e}"
|
||||
))
|
||||
})?;
|
||||
serialize_v8_value(scope, value, &mut ser).map_err(IpcError::SerdeJson)?;
|
||||
serialized.push(b'\n');
|
||||
|
||||
let stream = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<IpcJsonStreamResource>(rid)
|
||||
.map_err(|_| bad_resource_id())?;
|
||||
.map_err(IpcError::Resource)?;
|
||||
let old = stream
|
||||
.queued_bytes
|
||||
.fetch_add(serialized.len(), std::sync::atomic::Ordering::Relaxed);
|
||||
if old + serialized.len() > 2 * INITIAL_CAPACITY {
|
||||
// sending messages too fast
|
||||
let v = false.to_v8(scope)?;
|
||||
let v = false.to_v8(scope).unwrap(); // Infallible
|
||||
queue_ok.set_index(scope, 0, v);
|
||||
}
|
||||
Ok(async move {
|
||||
|
@ -246,12 +252,12 @@ mod impl_ {
|
|||
pub async fn op_node_ipc_read(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<serde_json::Value, AnyError> {
|
||||
) -> Result<serde_json::Value, IpcError> {
|
||||
let stream = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<IpcJsonStreamResource>(rid)
|
||||
.map_err(|_| bad_resource_id())?;
|
||||
.map_err(IpcError::Resource)?;
|
||||
|
||||
let cancel = stream.cancel.clone();
|
||||
let mut stream = RcRef::map(stream, |r| &r.read_half).borrow_mut().await;
|
||||
|
@ -407,7 +413,7 @@ mod impl_ {
|
|||
async fn write_msg_bytes(
|
||||
self: Rc<Self>,
|
||||
msg: &[u8],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), io::Error> {
|
||||
let mut write_half =
|
||||
RcRef::map(self, |r| &r.write_half).borrow_mut().await;
|
||||
write_half.write_all(msg).await?;
|
||||
|
@ -462,6 +468,14 @@ mod impl_ {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum IpcJsonStreamError {
|
||||
#[error("{0}")]
|
||||
Io(#[source] std::io::Error),
|
||||
#[error("{0}")]
|
||||
SimdJson(#[source] simd_json::Error),
|
||||
}
|
||||
|
||||
// JSON serialization stream over IPC pipe.
|
||||
//
|
||||
// `\n` is used as a delimiter between messages.
|
||||
|
@ -482,7 +496,7 @@ mod impl_ {
|
|||
|
||||
async fn read_msg(
|
||||
&mut self,
|
||||
) -> Result<Option<serde_json::Value>, AnyError> {
|
||||
) -> Result<Option<serde_json::Value>, IpcJsonStreamError> {
|
||||
let mut json = None;
|
||||
let nread = read_msg_inner(
|
||||
&mut self.pipe,
|
||||
|
@ -490,7 +504,8 @@ mod impl_ {
|
|||
&mut json,
|
||||
&mut self.read_buffer,
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(IpcJsonStreamError::Io)?;
|
||||
if nread == 0 {
|
||||
// EOF.
|
||||
return Ok(None);
|
||||
|
@ -500,7 +515,8 @@ mod impl_ {
|
|||
Some(v) => v,
|
||||
None => {
|
||||
// Took more than a single read and some buffering.
|
||||
simd_json::from_slice(&mut self.buffer[..nread])?
|
||||
simd_json::from_slice(&mut self.buffer[..nread])
|
||||
.map_err(IpcJsonStreamError::SimdJson)?
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,28 +1,38 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::NodePermissions;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
|
||||
mod cpus;
|
||||
mod priority;
|
||||
pub mod priority;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum OsError {
|
||||
#[error(transparent)]
|
||||
Priority(priority::PriorityError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
#[error("Failed to get cpu info")]
|
||||
FailedToGetCpuInfo,
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_node_os_get_priority<P>(
|
||||
state: &mut OpState,
|
||||
pid: u32,
|
||||
) -> Result<i32, AnyError>
|
||||
) -> Result<i32, OsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions.check_sys("getPriority", "node:os.getPriority()")?;
|
||||
permissions
|
||||
.check_sys("getPriority", "node:os.getPriority()")
|
||||
.map_err(OsError::Permission)?;
|
||||
}
|
||||
|
||||
priority::get_priority(pid)
|
||||
priority::get_priority(pid).map_err(OsError::Priority)
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
|
@ -30,21 +40,25 @@ pub fn op_node_os_set_priority<P>(
|
|||
state: &mut OpState,
|
||||
pid: u32,
|
||||
priority: i32,
|
||||
) -> Result<(), AnyError>
|
||||
) -> Result<(), OsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions.check_sys("setPriority", "node:os.setPriority()")?;
|
||||
permissions
|
||||
.check_sys("setPriority", "node:os.setPriority()")
|
||||
.map_err(OsError::Permission)?;
|
||||
}
|
||||
|
||||
priority::set_priority(pid, priority)
|
||||
priority::set_priority(pid, priority).map_err(OsError::Priority)
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[string]
|
||||
pub fn op_node_os_username<P>(state: &mut OpState) -> Result<String, AnyError>
|
||||
pub fn op_node_os_username<P>(
|
||||
state: &mut OpState,
|
||||
) -> Result<String, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -57,7 +71,9 @@ where
|
|||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_geteuid<P>(state: &mut OpState) -> Result<u32, AnyError>
|
||||
pub fn op_geteuid<P>(
|
||||
state: &mut OpState,
|
||||
) -> Result<u32, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -76,7 +92,9 @@ where
|
|||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_getegid<P>(state: &mut OpState) -> Result<u32, AnyError>
|
||||
pub fn op_getegid<P>(
|
||||
state: &mut OpState,
|
||||
) -> Result<u32, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -96,21 +114,25 @@ where
|
|||
|
||||
#[op2]
|
||||
#[serde]
|
||||
pub fn op_cpus<P>(state: &mut OpState) -> Result<Vec<cpus::CpuInfo>, AnyError>
|
||||
pub fn op_cpus<P>(state: &mut OpState) -> Result<Vec<cpus::CpuInfo>, OsError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions.check_sys("cpus", "node:os.cpus()")?;
|
||||
permissions
|
||||
.check_sys("cpus", "node:os.cpus()")
|
||||
.map_err(OsError::Permission)?;
|
||||
}
|
||||
|
||||
cpus::cpu_info().ok_or_else(|| type_error("Failed to get cpu info"))
|
||||
cpus::cpu_info().ok_or(OsError::FailedToGetCpuInfo)
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[string]
|
||||
pub fn op_homedir<P>(state: &mut OpState) -> Result<Option<String>, AnyError>
|
||||
pub fn op_homedir<P>(
|
||||
state: &mut OpState,
|
||||
) -> Result<Option<String>, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
|
||||
pub use impl_::*;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum PriorityError {
|
||||
#[error("{0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[cfg(windows)]
|
||||
#[error("Invalid priority")]
|
||||
InvalidPriority,
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
mod impl_ {
|
||||
use super::*;
|
||||
use errno::errno;
|
||||
use errno::set_errno;
|
||||
use errno::Errno;
|
||||
|
@ -16,7 +22,7 @@ mod impl_ {
|
|||
const PRIORITY_HIGH: i32 = -14;
|
||||
|
||||
// Ref: https://github.com/libuv/libuv/blob/55376b044b74db40772e8a6e24d67a8673998e02/src/unix/core.c#L1533-L1547
|
||||
pub fn get_priority(pid: u32) -> Result<i32, AnyError> {
|
||||
pub fn get_priority(pid: u32) -> Result<i32, super::PriorityError> {
|
||||
set_errno(Errno(0));
|
||||
match (
|
||||
// SAFETY: libc::getpriority is unsafe
|
||||
|
@ -29,7 +35,10 @@ mod impl_ {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> {
|
||||
pub fn set_priority(
|
||||
pid: u32,
|
||||
priority: i32,
|
||||
) -> Result<(), super::PriorityError> {
|
||||
// SAFETY: libc::setpriority is unsafe
|
||||
match unsafe { libc::setpriority(PRIO_PROCESS, pid as id_t, priority) } {
|
||||
-1 => Err(std::io::Error::last_os_error().into()),
|
||||
|
@ -40,8 +49,6 @@ mod impl_ {
|
|||
|
||||
#[cfg(windows)]
|
||||
mod impl_ {
|
||||
use super::*;
|
||||
use deno_core::error::type_error;
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
use winapi::shared::minwindef::FALSE;
|
||||
use winapi::shared::ntdef::NULL;
|
||||
|
@ -67,7 +74,7 @@ mod impl_ {
|
|||
const PRIORITY_HIGHEST: i32 = -20;
|
||||
|
||||
// Ported from: https://github.com/libuv/libuv/blob/a877ca2435134ef86315326ef4ef0c16bdbabf17/src/win/util.c#L1649-L1685
|
||||
pub fn get_priority(pid: u32) -> Result<i32, AnyError> {
|
||||
pub fn get_priority(pid: u32) -> Result<i32, super::PriorityError> {
|
||||
// SAFETY: Windows API calls
|
||||
unsafe {
|
||||
let handle = if pid == 0 {
|
||||
|
@ -95,7 +102,10 @@ mod impl_ {
|
|||
}
|
||||
|
||||
// Ported from: https://github.com/libuv/libuv/blob/a877ca2435134ef86315326ef4ef0c16bdbabf17/src/win/util.c#L1688-L1719
|
||||
pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> {
|
||||
pub fn set_priority(
|
||||
pid: u32,
|
||||
priority: i32,
|
||||
) -> Result<(), super::PriorityError> {
|
||||
// SAFETY: Windows API calls
|
||||
unsafe {
|
||||
let handle = if pid == 0 {
|
||||
|
@ -109,7 +119,7 @@ mod impl_ {
|
|||
#[allow(clippy::manual_range_contains)]
|
||||
let priority_class =
|
||||
if priority < PRIORITY_HIGHEST || priority > PRIORITY_LOW {
|
||||
return Err(type_error("Invalid priority"));
|
||||
return Err(super::PriorityError::InvalidPriority);
|
||||
} else if priority < PRIORITY_HIGH {
|
||||
REALTIME_PRIORITY_CLASS
|
||||
} else if priority < PRIORITY_ABOVE_NORMAL {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_permissions::PermissionsContainer;
|
||||
|
@ -51,7 +50,7 @@ pub fn op_node_process_kill(
|
|||
state: &mut OpState,
|
||||
#[smi] pid: i32,
|
||||
#[smi] sig: i32,
|
||||
) -> Result<i32, AnyError> {
|
||||
) -> Result<i32, deno_core::error::AnyError> {
|
||||
state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_run_all("process.kill")?;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::v8;
|
||||
|
@ -30,7 +27,7 @@ use crate::NpmResolverRc;
|
|||
fn ensure_read_permission<'a, P>(
|
||||
state: &mut OpState,
|
||||
file_path: &'a Path,
|
||||
) -> Result<Cow<'a, Path>, AnyError>
|
||||
) -> Result<Cow<'a, Path>, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -39,6 +36,32 @@ where
|
|||
resolver.ensure_read_permission(permissions, file_path)
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum RequireError {
|
||||
#[error(transparent)]
|
||||
UrlParse(#[from] url::ParseError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
PackageExportsResolve(
|
||||
#[from] node_resolver::errors::PackageExportsResolveError,
|
||||
),
|
||||
#[error(transparent)]
|
||||
PackageJsonLoad(#[from] node_resolver::errors::PackageJsonLoadError),
|
||||
#[error(transparent)]
|
||||
ClosestPkgJson(#[from] node_resolver::errors::ClosestPkgJsonError),
|
||||
#[error(transparent)]
|
||||
PackageImportsResolve(
|
||||
#[from] node_resolver::errors::PackageImportsResolveError,
|
||||
),
|
||||
#[error("failed to convert '{0}' to file path")]
|
||||
FilePathConversion(Url),
|
||||
#[error(transparent)]
|
||||
Fs(#[from] deno_io::fs::FsError),
|
||||
#[error("Unable to get CWD: {0}")]
|
||||
UnableToGetCwd(deno_io::fs::FsError),
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[serde]
|
||||
pub fn op_require_init_paths() -> Vec<String> {
|
||||
|
@ -95,7 +118,7 @@ pub fn op_require_init_paths() -> Vec<String> {
|
|||
pub fn op_require_node_module_paths<P>(
|
||||
state: &mut OpState,
|
||||
#[string] from: String,
|
||||
) -> Result<Vec<String>, AnyError>
|
||||
) -> Result<Vec<String>, RequireError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -104,12 +127,12 @@ where
|
|||
let from = if from.starts_with("file:///") {
|
||||
url_to_file_path(&Url::parse(&from)?)?
|
||||
} else {
|
||||
let current_dir =
|
||||
&(fs.cwd().map_err(AnyError::from)).context("Unable to get CWD")?;
|
||||
deno_path_util::normalize_path(current_dir.join(from))
|
||||
let current_dir = &fs.cwd().map_err(RequireError::UnableToGetCwd)?;
|
||||
normalize_path(current_dir.join(from))
|
||||
};
|
||||
|
||||
let from = ensure_read_permission::<P>(state, &from)?;
|
||||
let from = ensure_read_permission::<P>(state, &from)
|
||||
.map_err(RequireError::Permission)?;
|
||||
|
||||
if cfg!(windows) {
|
||||
// return root node_modules when path is 'D:\\'.
|
||||
|
@ -264,7 +287,7 @@ pub fn op_require_path_is_absolute(#[string] p: String) -> bool {
|
|||
pub fn op_require_stat<P>(
|
||||
state: &mut OpState,
|
||||
#[string] path: String,
|
||||
) -> Result<i32, AnyError>
|
||||
) -> Result<i32, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -287,12 +310,13 @@ where
|
|||
pub fn op_require_real_path<P>(
|
||||
state: &mut OpState,
|
||||
#[string] request: String,
|
||||
) -> Result<String, AnyError>
|
||||
) -> Result<String, RequireError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let path = PathBuf::from(request);
|
||||
let path = ensure_read_permission::<P>(state, &path)?;
|
||||
let path = ensure_read_permission::<P>(state, &path)
|
||||
.map_err(RequireError::Permission)?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
let canonicalized_path =
|
||||
deno_path_util::strip_unc_prefix(fs.realpath_sync(&path)?);
|
||||
|
@ -319,12 +343,14 @@ pub fn op_require_path_resolve(#[serde] parts: Vec<String>) -> String {
|
|||
#[string]
|
||||
pub fn op_require_path_dirname(
|
||||
#[string] request: String,
|
||||
) -> Result<String, AnyError> {
|
||||
) -> Result<String, deno_core::error::AnyError> {
|
||||
let p = PathBuf::from(request);
|
||||
if let Some(parent) = p.parent() {
|
||||
Ok(parent.to_string_lossy().into_owned())
|
||||
} else {
|
||||
Err(generic_error("Path doesn't have a parent"))
|
||||
Err(deno_core::error::generic_error(
|
||||
"Path doesn't have a parent",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,12 +358,14 @@ pub fn op_require_path_dirname(
|
|||
#[string]
|
||||
pub fn op_require_path_basename(
|
||||
#[string] request: String,
|
||||
) -> Result<String, AnyError> {
|
||||
) -> Result<String, deno_core::error::AnyError> {
|
||||
let p = PathBuf::from(request);
|
||||
if let Some(path) = p.file_name() {
|
||||
Ok(path.to_string_lossy().into_owned())
|
||||
} else {
|
||||
Err(generic_error("Path doesn't have a file name"))
|
||||
Err(deno_core::error::generic_error(
|
||||
"Path doesn't have a file name",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,7 +376,7 @@ pub fn op_require_try_self_parent_path<P>(
|
|||
has_parent: bool,
|
||||
#[string] maybe_parent_filename: Option<String>,
|
||||
#[string] maybe_parent_id: Option<String>,
|
||||
) -> Result<Option<String>, AnyError>
|
||||
) -> Result<Option<String>, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -378,7 +406,7 @@ pub fn op_require_try_self<P>(
|
|||
state: &mut OpState,
|
||||
#[string] parent_path: Option<String>,
|
||||
#[string] request: String,
|
||||
) -> Result<Option<String>, AnyError>
|
||||
) -> Result<Option<String>, RequireError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -440,12 +468,13 @@ where
|
|||
pub fn op_require_read_file<P>(
|
||||
state: &mut OpState,
|
||||
#[string] file_path: String,
|
||||
) -> Result<String, AnyError>
|
||||
) -> Result<String, RequireError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let file_path = PathBuf::from(file_path);
|
||||
let file_path = ensure_read_permission::<P>(state, &file_path)?;
|
||||
let file_path = ensure_read_permission::<P>(state, &file_path)
|
||||
.map_err(RequireError::Permission)?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
Ok(fs.read_text_file_lossy_sync(&file_path, None)?)
|
||||
}
|
||||
|
@ -472,7 +501,7 @@ pub fn op_require_resolve_exports<P>(
|
|||
#[string] name: String,
|
||||
#[string] expansion: String,
|
||||
#[string] parent_path: String,
|
||||
) -> Result<Option<String>, AnyError>
|
||||
) -> Result<Option<String>, RequireError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -525,16 +554,14 @@ where
|
|||
pub fn op_require_read_closest_package_json<P>(
|
||||
state: &mut OpState,
|
||||
#[string] filename: String,
|
||||
) -> Result<Option<PackageJsonRc>, AnyError>
|
||||
) -> Result<Option<PackageJsonRc>, node_resolver::errors::ClosestPkgJsonError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let filename = PathBuf::from(filename);
|
||||
// permissions: allow reading the closest package.json files
|
||||
let node_resolver = state.borrow::<NodeResolverRc>().clone();
|
||||
node_resolver
|
||||
.get_closest_package_json_from_path(&filename)
|
||||
.map_err(AnyError::from)
|
||||
node_resolver.get_closest_package_json_from_path(&filename)
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
@ -564,12 +591,13 @@ pub fn op_require_package_imports_resolve<P>(
|
|||
state: &mut OpState,
|
||||
#[string] referrer_filename: String,
|
||||
#[string] request: String,
|
||||
) -> Result<Option<String>, AnyError>
|
||||
) -> Result<Option<String>, RequireError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
let referrer_path = PathBuf::from(&referrer_filename);
|
||||
let referrer_path = ensure_read_permission::<P>(state, &referrer_path)?;
|
||||
let referrer_path = ensure_read_permission::<P>(state, &referrer_path)
|
||||
.map_err(RequireError::Permission)?;
|
||||
let node_resolver = state.borrow::<NodeResolverRc>();
|
||||
let Some(pkg) =
|
||||
node_resolver.get_closest_package_json_from_path(&referrer_path)?
|
||||
|
@ -578,8 +606,7 @@ where
|
|||
};
|
||||
|
||||
if pkg.imports.is_some() {
|
||||
let referrer_url =
|
||||
deno_core::url::Url::from_file_path(&referrer_filename).unwrap();
|
||||
let referrer_url = Url::from_file_path(&referrer_filename).unwrap();
|
||||
let url = node_resolver.package_imports_resolve(
|
||||
&request,
|
||||
Some(&referrer_url),
|
||||
|
@ -604,17 +631,15 @@ pub fn op_require_break_on_next_statement(state: Rc<RefCell<OpState>>) {
|
|||
inspector.wait_for_session_and_break_on_next_statement()
|
||||
}
|
||||
|
||||
fn url_to_file_path_string(url: &Url) -> Result<String, AnyError> {
|
||||
fn url_to_file_path_string(url: &Url) -> Result<String, RequireError> {
|
||||
let file_path = url_to_file_path(url)?;
|
||||
Ok(file_path.to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
fn url_to_file_path(url: &Url) -> Result<PathBuf, AnyError> {
|
||||
fn url_to_file_path(url: &Url) -> Result<PathBuf, RequireError> {
|
||||
match url.to_file_path() {
|
||||
Ok(file_path) => Ok(file_path),
|
||||
Err(()) => {
|
||||
deno_core::anyhow::bail!("failed to convert '{}' to file path", url)
|
||||
}
|
||||
Err(()) => Err(RequireError::FilePathConversion(url.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ResourceHandle;
|
||||
|
@ -22,7 +21,7 @@ enum HandleType {
|
|||
pub fn op_node_guess_handle_type(
|
||||
state: &mut OpState,
|
||||
rid: u32,
|
||||
) -> Result<u32, AnyError> {
|
||||
) -> Result<u32, deno_core::error::AnyError> {
|
||||
let handle = state.resource_table.get_handle(rid)?;
|
||||
|
||||
let handle_type = match handle {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_core::FastString;
|
||||
|
@ -206,10 +204,9 @@ pub fn op_v8_write_value(
|
|||
scope: &mut v8::HandleScope,
|
||||
#[cppgc] ser: &Serializer,
|
||||
value: v8::Local<v8::Value>,
|
||||
) -> Result<(), AnyError> {
|
||||
) {
|
||||
let context = scope.get_current_context();
|
||||
ser.inner.write_value(context, value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct DeserBuffer {
|
||||
|
@ -271,11 +268,13 @@ pub fn op_v8_new_deserializer(
|
|||
scope: &mut v8::HandleScope,
|
||||
obj: v8::Local<v8::Object>,
|
||||
buffer: v8::Local<v8::ArrayBufferView>,
|
||||
) -> Result<Deserializer<'static>, AnyError> {
|
||||
) -> Result<Deserializer<'static>, deno_core::error::AnyError> {
|
||||
let offset = buffer.byte_offset();
|
||||
let len = buffer.byte_length();
|
||||
let backing_store = buffer.get_backing_store().ok_or_else(|| {
|
||||
generic_error("deserialization buffer has no backing store")
|
||||
deno_core::error::generic_error(
|
||||
"deserialization buffer has no backing store",
|
||||
)
|
||||
})?;
|
||||
let (buf_slice, buf_ptr) = if let Some(data) = backing_store.data() {
|
||||
// SAFETY: the offset is valid for the underlying buffer because we're getting it directly from v8
|
||||
|
@ -317,10 +316,10 @@ pub fn op_v8_transfer_array_buffer_de(
|
|||
#[op2(fast)]
|
||||
pub fn op_v8_read_double(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> Result<f64, AnyError> {
|
||||
) -> Result<f64, deno_core::error::AnyError> {
|
||||
let mut double = 0f64;
|
||||
if !deser.inner.read_double(&mut double) {
|
||||
return Err(type_error("ReadDouble() failed"));
|
||||
return Err(deno_core::error::type_error("ReadDouble() failed"));
|
||||
}
|
||||
Ok(double)
|
||||
}
|
||||
|
@ -355,10 +354,10 @@ pub fn op_v8_read_raw_bytes(
|
|||
#[op2(fast)]
|
||||
pub fn op_v8_read_uint32(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> Result<u32, AnyError> {
|
||||
) -> Result<u32, deno_core::error::AnyError> {
|
||||
let mut value = 0;
|
||||
if !deser.inner.read_uint32(&mut value) {
|
||||
return Err(type_error("ReadUint32() failed"));
|
||||
return Err(deno_core::error::type_error("ReadUint32() failed"));
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
|
@ -368,10 +367,10 @@ pub fn op_v8_read_uint32(
|
|||
#[serde]
|
||||
pub fn op_v8_read_uint64(
|
||||
#[cppgc] deser: &Deserializer,
|
||||
) -> Result<(u32, u32), AnyError> {
|
||||
) -> Result<(u32, u32), deno_core::error::AnyError> {
|
||||
let mut val = 0;
|
||||
if !deser.inner.read_uint64(&mut val) {
|
||||
return Err(type_error("ReadUint64() failed"));
|
||||
return Err(deno_core::error::type_error("ReadUint64() failed"));
|
||||
}
|
||||
|
||||
Ok(((val >> 32) as u32, val as u32))
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::OpState;
|
||||
|
@ -19,7 +17,7 @@ use crate::NodeResolverRc;
|
|||
fn ensure_read_permission<'a, P>(
|
||||
state: &mut OpState,
|
||||
file_path: &'a Path,
|
||||
) -> Result<Cow<'a, Path>, AnyError>
|
||||
) -> Result<Cow<'a, Path>, deno_core::error::AnyError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -28,12 +26,36 @@ where
|
|||
resolver.ensure_read_permission(permissions, file_path)
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum WorkerThreadsFilenameError {
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
#[error("{0}")]
|
||||
UrlParse(#[from] url::ParseError),
|
||||
#[error("Relative path entries must start with '.' or '..'")]
|
||||
InvalidRelativeUrl,
|
||||
#[error("URL from Path-String")]
|
||||
UrlFromPathString,
|
||||
#[error("URL to Path-String")]
|
||||
UrlToPathString,
|
||||
#[error("URL to Path")]
|
||||
UrlToPath,
|
||||
#[error("File not found [{0:?}]")]
|
||||
FileNotFound(PathBuf),
|
||||
#[error("Neither ESM nor CJS")]
|
||||
NeitherEsmNorCjs,
|
||||
#[error("{0}")]
|
||||
UrlToNodeResolution(node_resolver::errors::UrlToNodeResolutionError),
|
||||
#[error(transparent)]
|
||||
Fs(#[from] deno_io::fs::FsError),
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[string]
|
||||
pub fn op_worker_threads_filename<P>(
|
||||
state: &mut OpState,
|
||||
#[string] specifier: String,
|
||||
) -> Result<String, AnyError>
|
||||
) -> Result<String, WorkerThreadsFilenameError>
|
||||
where
|
||||
P: NodePermissions + 'static,
|
||||
{
|
||||
|
@ -45,40 +67,47 @@ where
|
|||
} else {
|
||||
let path = PathBuf::from(&specifier);
|
||||
if path.is_relative() && !specifier.starts_with('.') {
|
||||
return Err(generic_error(
|
||||
"Relative path entries must start with '.' or '..'",
|
||||
));
|
||||
return Err(WorkerThreadsFilenameError::InvalidRelativeUrl);
|
||||
}
|
||||
let path = ensure_read_permission::<P>(state, &path)?;
|
||||
let path = ensure_read_permission::<P>(state, &path)
|
||||
.map_err(WorkerThreadsFilenameError::Permission)?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
let canonicalized_path =
|
||||
deno_path_util::strip_unc_prefix(fs.realpath_sync(&path)?);
|
||||
Url::from_file_path(canonicalized_path)
|
||||
.map_err(|e| generic_error(format!("URL from Path-String: {:#?}", e)))?
|
||||
.map_err(|_| WorkerThreadsFilenameError::UrlFromPathString)?
|
||||
};
|
||||
let url_path = url
|
||||
.to_file_path()
|
||||
.map_err(|e| generic_error(format!("URL to Path-String: {:#?}", e)))?;
|
||||
let url_path = ensure_read_permission::<P>(state, &url_path)?;
|
||||
.map_err(|_| WorkerThreadsFilenameError::UrlToPathString)?;
|
||||
let url_path = ensure_read_permission::<P>(state, &url_path)
|
||||
.map_err(WorkerThreadsFilenameError::Permission)?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
if !fs.exists_sync(&url_path) {
|
||||
return Err(generic_error(format!("File not found [{:?}]", url_path)));
|
||||
return Err(WorkerThreadsFilenameError::FileNotFound(
|
||||
url_path.to_path_buf(),
|
||||
));
|
||||
}
|
||||
let node_resolver = state.borrow::<NodeResolverRc>();
|
||||
match node_resolver.url_to_node_resolution(url)? {
|
||||
match node_resolver
|
||||
.url_to_node_resolution(url)
|
||||
.map_err(WorkerThreadsFilenameError::UrlToNodeResolution)?
|
||||
{
|
||||
NodeResolution::Esm(u) => Ok(u.to_string()),
|
||||
NodeResolution::CommonJs(u) => wrap_cjs(u),
|
||||
NodeResolution::BuiltIn(_) => Err(generic_error("Neither ESM nor CJS")),
|
||||
NodeResolution::BuiltIn(_) => {
|
||||
Err(WorkerThreadsFilenameError::NeitherEsmNorCjs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Wrap a CJS file-URL and the required setup in a stringified `data:`-URL
|
||||
///
|
||||
fn wrap_cjs(url: Url) -> Result<String, AnyError> {
|
||||
fn wrap_cjs(url: Url) -> Result<String, WorkerThreadsFilenameError> {
|
||||
let path = url
|
||||
.to_file_path()
|
||||
.map_err(|e| generic_error(format!("URL to Path: {:#?}", e)))?;
|
||||
.map_err(|_| WorkerThreadsFilenameError::UrlToPath)?;
|
||||
let filename = path.file_name().unwrap().to_string_lossy();
|
||||
Ok(format!(
|
||||
"data:text/javascript,import {{ createRequire }} from \"node:module\";\
|
||||
|
|
|
@ -9,8 +9,6 @@ use brotli::BrotliDecompressStream;
|
|||
use brotli::BrotliResult;
|
||||
use brotli::BrotliState;
|
||||
use brotli::Decompressor;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::JsBuffer;
|
||||
use deno_core::OpState;
|
||||
|
@ -19,7 +17,23 @@ use deno_core::ToJsBuffer;
|
|||
use std::cell::RefCell;
|
||||
use std::io::Read;
|
||||
|
||||
fn encoder_mode(mode: u32) -> Result<BrotliEncoderMode, AnyError> {
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum BrotliError {
|
||||
#[error("Invalid encoder mode")]
|
||||
InvalidEncoderMode,
|
||||
#[error("Failed to compress")]
|
||||
CompressFailed,
|
||||
#[error("Failed to decompress")]
|
||||
DecompressFailed,
|
||||
#[error(transparent)]
|
||||
Join(#[from] tokio::task::JoinError),
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error("{0}")]
|
||||
Io(std::io::Error),
|
||||
}
|
||||
|
||||
fn encoder_mode(mode: u32) -> Result<BrotliEncoderMode, BrotliError> {
|
||||
Ok(match mode {
|
||||
0 => BrotliEncoderMode::BROTLI_MODE_GENERIC,
|
||||
1 => BrotliEncoderMode::BROTLI_MODE_TEXT,
|
||||
|
@ -28,7 +42,7 @@ fn encoder_mode(mode: u32) -> Result<BrotliEncoderMode, AnyError> {
|
|||
4 => BrotliEncoderMode::BROTLI_FORCE_MSB_PRIOR,
|
||||
5 => BrotliEncoderMode::BROTLI_FORCE_UTF8_PRIOR,
|
||||
6 => BrotliEncoderMode::BROTLI_FORCE_SIGNED_PRIOR,
|
||||
_ => return Err(type_error("Invalid encoder mode")),
|
||||
_ => return Err(BrotliError::InvalidEncoderMode),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -40,7 +54,7 @@ pub fn op_brotli_compress(
|
|||
#[smi] quality: i32,
|
||||
#[smi] lgwin: i32,
|
||||
#[smi] mode: u32,
|
||||
) -> Result<usize, AnyError> {
|
||||
) -> Result<usize, BrotliError> {
|
||||
let mode = encoder_mode(mode)?;
|
||||
let mut out_size = out.len();
|
||||
|
||||
|
@ -57,7 +71,7 @@ pub fn op_brotli_compress(
|
|||
&mut |_, _, _, _| (),
|
||||
);
|
||||
if result != 1 {
|
||||
return Err(type_error("Failed to compress"));
|
||||
return Err(BrotliError::CompressFailed);
|
||||
}
|
||||
|
||||
Ok(out_size)
|
||||
|
@ -87,7 +101,7 @@ pub async fn op_brotli_compress_async(
|
|||
#[smi] quality: i32,
|
||||
#[smi] lgwin: i32,
|
||||
#[smi] mode: u32,
|
||||
) -> Result<ToJsBuffer, AnyError> {
|
||||
) -> Result<ToJsBuffer, BrotliError> {
|
||||
let mode = encoder_mode(mode)?;
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let input = &*input;
|
||||
|
@ -107,7 +121,7 @@ pub async fn op_brotli_compress_async(
|
|||
&mut |_, _, _, _| (),
|
||||
);
|
||||
if result != 1 {
|
||||
return Err(type_error("Failed to compress"));
|
||||
return Err(BrotliError::CompressFailed);
|
||||
}
|
||||
|
||||
out.truncate(out_size);
|
||||
|
@ -151,8 +165,11 @@ pub fn op_brotli_compress_stream(
|
|||
#[smi] rid: u32,
|
||||
#[buffer] input: &[u8],
|
||||
#[buffer] output: &mut [u8],
|
||||
) -> Result<usize, AnyError> {
|
||||
let ctx = state.resource_table.get::<BrotliCompressCtx>(rid)?;
|
||||
) -> Result<usize, BrotliError> {
|
||||
let ctx = state
|
||||
.resource_table
|
||||
.get::<BrotliCompressCtx>(rid)
|
||||
.map_err(BrotliError::Resource)?;
|
||||
let mut inst = ctx.inst.borrow_mut();
|
||||
let mut output_offset = 0;
|
||||
|
||||
|
@ -168,7 +185,7 @@ pub fn op_brotli_compress_stream(
|
|||
&mut |_, _, _, _| (),
|
||||
);
|
||||
if !result {
|
||||
return Err(type_error("Failed to compress"));
|
||||
return Err(BrotliError::CompressFailed);
|
||||
}
|
||||
|
||||
Ok(output_offset)
|
||||
|
@ -180,8 +197,11 @@ pub fn op_brotli_compress_stream_end(
|
|||
state: &mut OpState,
|
||||
#[smi] rid: u32,
|
||||
#[buffer] output: &mut [u8],
|
||||
) -> Result<usize, AnyError> {
|
||||
let ctx = state.resource_table.get::<BrotliCompressCtx>(rid)?;
|
||||
) -> Result<usize, BrotliError> {
|
||||
let ctx = state
|
||||
.resource_table
|
||||
.get::<BrotliCompressCtx>(rid)
|
||||
.map_err(BrotliError::Resource)?;
|
||||
let mut inst = ctx.inst.borrow_mut();
|
||||
let mut output_offset = 0;
|
||||
|
||||
|
@ -197,13 +217,13 @@ pub fn op_brotli_compress_stream_end(
|
|||
&mut |_, _, _, _| (),
|
||||
);
|
||||
if !result {
|
||||
return Err(type_error("Failed to compress"));
|
||||
return Err(BrotliError::CompressFailed);
|
||||
}
|
||||
|
||||
Ok(output_offset)
|
||||
}
|
||||
|
||||
fn brotli_decompress(buffer: &[u8]) -> Result<ToJsBuffer, AnyError> {
|
||||
fn brotli_decompress(buffer: &[u8]) -> Result<ToJsBuffer, std::io::Error> {
|
||||
let mut output = Vec::with_capacity(4096);
|
||||
let mut decompressor = Decompressor::new(buffer, buffer.len());
|
||||
decompressor.read_to_end(&mut output)?;
|
||||
|
@ -214,7 +234,7 @@ fn brotli_decompress(buffer: &[u8]) -> Result<ToJsBuffer, AnyError> {
|
|||
#[serde]
|
||||
pub fn op_brotli_decompress(
|
||||
#[buffer] buffer: &[u8],
|
||||
) -> Result<ToJsBuffer, AnyError> {
|
||||
) -> Result<ToJsBuffer, std::io::Error> {
|
||||
brotli_decompress(buffer)
|
||||
}
|
||||
|
||||
|
@ -222,8 +242,11 @@ pub fn op_brotli_decompress(
|
|||
#[serde]
|
||||
pub async fn op_brotli_decompress_async(
|
||||
#[buffer] buffer: JsBuffer,
|
||||
) -> Result<ToJsBuffer, AnyError> {
|
||||
tokio::task::spawn_blocking(move || brotli_decompress(&buffer)).await?
|
||||
) -> Result<ToJsBuffer, BrotliError> {
|
||||
tokio::task::spawn_blocking(move || {
|
||||
brotli_decompress(&buffer).map_err(BrotliError::Io)
|
||||
})
|
||||
.await?
|
||||
}
|
||||
|
||||
struct BrotliDecompressCtx {
|
||||
|
@ -252,8 +275,11 @@ pub fn op_brotli_decompress_stream(
|
|||
#[smi] rid: u32,
|
||||
#[buffer] input: &[u8],
|
||||
#[buffer] output: &mut [u8],
|
||||
) -> Result<usize, AnyError> {
|
||||
let ctx = state.resource_table.get::<BrotliDecompressCtx>(rid)?;
|
||||
) -> Result<usize, BrotliError> {
|
||||
let ctx = state
|
||||
.resource_table
|
||||
.get::<BrotliDecompressCtx>(rid)
|
||||
.map_err(BrotliError::Resource)?;
|
||||
let mut inst = ctx.inst.borrow_mut();
|
||||
let mut output_offset = 0;
|
||||
|
||||
|
@ -268,7 +294,7 @@ pub fn op_brotli_decompress_stream(
|
|||
&mut inst,
|
||||
);
|
||||
if matches!(result, BrotliResult::ResultFailure) {
|
||||
return Err(type_error("Failed to decompress"));
|
||||
return Err(BrotliError::DecompressFailed);
|
||||
}
|
||||
|
||||
Ok(output_offset)
|
||||
|
@ -280,8 +306,11 @@ pub fn op_brotli_decompress_stream_end(
|
|||
state: &mut OpState,
|
||||
#[smi] rid: u32,
|
||||
#[buffer] output: &mut [u8],
|
||||
) -> Result<usize, AnyError> {
|
||||
let ctx = state.resource_table.get::<BrotliDecompressCtx>(rid)?;
|
||||
) -> Result<usize, BrotliError> {
|
||||
let ctx = state
|
||||
.resource_table
|
||||
.get::<BrotliDecompressCtx>(rid)
|
||||
.map_err(BrotliError::Resource)?;
|
||||
let mut inst = ctx.inst.borrow_mut();
|
||||
let mut output_offset = 0;
|
||||
|
||||
|
@ -296,7 +325,7 @@ pub fn op_brotli_decompress_stream_end(
|
|||
&mut inst,
|
||||
);
|
||||
if matches!(result, BrotliResult::ResultFailure) {
|
||||
return Err(type_error("Failed to decompress"));
|
||||
return Err(BrotliError::DecompressFailed);
|
||||
}
|
||||
|
||||
Ok(output_offset)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
|
||||
use deno_core::op2;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
|
@ -8,7 +7,7 @@ use zlib::*;
|
|||
|
||||
mod alloc;
|
||||
pub mod brotli;
|
||||
mod mode;
|
||||
pub mod mode;
|
||||
mod stream;
|
||||
|
||||
use mode::Flush;
|
||||
|
@ -17,11 +16,11 @@ use mode::Mode;
|
|||
use self::stream::StreamWrapper;
|
||||
|
||||
#[inline]
|
||||
fn check(condition: bool, msg: &str) -> Result<(), AnyError> {
|
||||
fn check(condition: bool, msg: &str) -> Result<(), deno_core::error::AnyError> {
|
||||
if condition {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(type_error(msg.to_string()))
|
||||
Err(deno_core::error::type_error(msg.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +55,7 @@ impl ZlibInner {
|
|||
out_off: u32,
|
||||
out_len: u32,
|
||||
flush: Flush,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
check(self.init_done, "write before init")?;
|
||||
check(!self.write_in_progress, "write already in progress")?;
|
||||
check(!self.pending_close, "close already in progress")?;
|
||||
|
@ -65,11 +64,11 @@ impl ZlibInner {
|
|||
|
||||
let next_in = input
|
||||
.get(in_off as usize..in_off as usize + in_len as usize)
|
||||
.ok_or_else(|| type_error("invalid input range"))?
|
||||
.ok_or_else(|| deno_core::error::type_error("invalid input range"))?
|
||||
.as_ptr() as *mut _;
|
||||
let next_out = out
|
||||
.get_mut(out_off as usize..out_off as usize + out_len as usize)
|
||||
.ok_or_else(|| type_error("invalid output range"))?
|
||||
.ok_or_else(|| deno_core::error::type_error("invalid output range"))?
|
||||
.as_mut_ptr();
|
||||
|
||||
self.strm.avail_in = in_len;
|
||||
|
@ -81,7 +80,10 @@ impl ZlibInner {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn do_write(&mut self, flush: Flush) -> Result<(), AnyError> {
|
||||
fn do_write(
|
||||
&mut self,
|
||||
flush: Flush,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
self.flush = flush;
|
||||
match self.mode {
|
||||
Mode::Deflate | Mode::Gzip | Mode::DeflateRaw => {
|
||||
|
@ -127,7 +129,7 @@ impl ZlibInner {
|
|||
self.mode = Mode::Inflate;
|
||||
}
|
||||
} else if next_expected_header_byte.is_some() {
|
||||
return Err(type_error(
|
||||
return Err(deno_core::error::type_error(
|
||||
"invalid number of gzip magic number bytes read",
|
||||
));
|
||||
}
|
||||
|
@ -181,7 +183,7 @@ impl ZlibInner {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn init_stream(&mut self) -> Result<(), AnyError> {
|
||||
fn init_stream(&mut self) -> Result<(), deno_core::error::AnyError> {
|
||||
match self.mode {
|
||||
Mode::Gzip | Mode::Gunzip => self.window_bits += 16,
|
||||
Mode::Unzip => self.window_bits += 32,
|
||||
|
@ -199,7 +201,7 @@ impl ZlibInner {
|
|||
Mode::Inflate | Mode::Gunzip | Mode::InflateRaw | Mode::Unzip => {
|
||||
self.strm.inflate_init(self.window_bits)
|
||||
}
|
||||
Mode::None => return Err(type_error("Unknown mode")),
|
||||
Mode::None => return Err(deno_core::error::type_error("Unknown mode")),
|
||||
};
|
||||
|
||||
self.write_in_progress = false;
|
||||
|
@ -208,7 +210,7 @@ impl ZlibInner {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&mut self) -> Result<bool, AnyError> {
|
||||
fn close(&mut self) -> Result<bool, deno_core::error::AnyError> {
|
||||
if self.write_in_progress {
|
||||
self.pending_close = true;
|
||||
return Ok(false);
|
||||
|
@ -222,10 +224,8 @@ impl ZlibInner {
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
fn reset_stream(&mut self) -> Result<(), AnyError> {
|
||||
fn reset_stream(&mut self) {
|
||||
self.err = self.strm.reset(self.mode);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ impl deno_core::Resource for Zlib {
|
|||
|
||||
#[op2]
|
||||
#[cppgc]
|
||||
pub fn op_zlib_new(#[smi] mode: i32) -> Result<Zlib, AnyError> {
|
||||
pub fn op_zlib_new(#[smi] mode: i32) -> Result<Zlib, mode::ModeError> {
|
||||
let mode = Mode::try_from(mode)?;
|
||||
|
||||
let inner = ZlibInner {
|
||||
|
@ -256,12 +256,20 @@ pub fn op_zlib_new(#[smi] mode: i32) -> Result<Zlib, AnyError> {
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ZlibError {
|
||||
#[error("zlib not initialized")]
|
||||
NotInitialized,
|
||||
#[error(transparent)]
|
||||
Mode(#[from] mode::ModeError),
|
||||
#[error(transparent)]
|
||||
Other(#[from] deno_core::error::AnyError),
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
pub fn op_zlib_close(#[cppgc] resource: &Zlib) -> Result<(), AnyError> {
|
||||
pub fn op_zlib_close(#[cppgc] resource: &Zlib) -> Result<(), ZlibError> {
|
||||
let mut resource = resource.inner.borrow_mut();
|
||||
let zlib = resource
|
||||
.as_mut()
|
||||
.ok_or_else(|| type_error("zlib not initialized"))?;
|
||||
let zlib = resource.as_mut().ok_or(ZlibError::NotInitialized)?;
|
||||
|
||||
// If there is a pending write, defer the close until the write is done.
|
||||
zlib.close()?;
|
||||
|
@ -282,11 +290,9 @@ pub fn op_zlib_write(
|
|||
#[smi] out_off: u32,
|
||||
#[smi] out_len: u32,
|
||||
#[buffer] result: &mut [u32],
|
||||
) -> Result<i32, AnyError> {
|
||||
) -> Result<i32, ZlibError> {
|
||||
let mut zlib = resource.inner.borrow_mut();
|
||||
let zlib = zlib
|
||||
.as_mut()
|
||||
.ok_or_else(|| type_error("zlib not initialized"))?;
|
||||
let zlib = zlib.as_mut().ok_or(ZlibError::NotInitialized)?;
|
||||
|
||||
let flush = Flush::try_from(flush)?;
|
||||
zlib.start_write(input, in_off, in_len, out, out_off, out_len, flush)?;
|
||||
|
@ -307,11 +313,9 @@ pub fn op_zlib_init(
|
|||
#[smi] mem_level: i32,
|
||||
#[smi] strategy: i32,
|
||||
#[buffer] dictionary: &[u8],
|
||||
) -> Result<i32, AnyError> {
|
||||
) -> Result<i32, ZlibError> {
|
||||
let mut zlib = resource.inner.borrow_mut();
|
||||
let zlib = zlib
|
||||
.as_mut()
|
||||
.ok_or_else(|| type_error("zlib not initialized"))?;
|
||||
let zlib = zlib.as_mut().ok_or(ZlibError::NotInitialized)?;
|
||||
|
||||
check((8..=15).contains(&window_bits), "invalid windowBits")?;
|
||||
check((-1..=9).contains(&level), "invalid level")?;
|
||||
|
@ -348,13 +352,11 @@ pub fn op_zlib_init(
|
|||
|
||||
#[op2(fast)]
|
||||
#[smi]
|
||||
pub fn op_zlib_reset(#[cppgc] resource: &Zlib) -> Result<i32, AnyError> {
|
||||
pub fn op_zlib_reset(#[cppgc] resource: &Zlib) -> Result<i32, ZlibError> {
|
||||
let mut zlib = resource.inner.borrow_mut();
|
||||
let zlib = zlib
|
||||
.as_mut()
|
||||
.ok_or_else(|| type_error("zlib not initialized"))?;
|
||||
let zlib = zlib.as_mut().ok_or(ZlibError::NotInitialized)?;
|
||||
|
||||
zlib.reset_stream()?;
|
||||
zlib.reset_stream();
|
||||
|
||||
Ok(zlib.err)
|
||||
}
|
||||
|
@ -362,12 +364,10 @@ pub fn op_zlib_reset(#[cppgc] resource: &Zlib) -> Result<i32, AnyError> {
|
|||
#[op2(fast)]
|
||||
pub fn op_zlib_close_if_pending(
|
||||
#[cppgc] resource: &Zlib,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), ZlibError> {
|
||||
let pending_close = {
|
||||
let mut zlib = resource.inner.borrow_mut();
|
||||
let zlib = zlib
|
||||
.as_mut()
|
||||
.ok_or_else(|| type_error("zlib not initialized"))?;
|
||||
let zlib = zlib.as_mut().ok_or(ZlibError::NotInitialized)?;
|
||||
|
||||
zlib.write_in_progress = false;
|
||||
zlib.pending_close
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
BadArgument,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Error::BadArgument => write!(f, "bad argument"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("bad argument")]
|
||||
pub struct ModeError;
|
||||
|
||||
macro_rules! repr_i32 {
|
||||
($(#[$meta:meta])* $vis:vis enum $name:ident {
|
||||
|
@ -25,12 +14,12 @@ macro_rules! repr_i32 {
|
|||
}
|
||||
|
||||
impl core::convert::TryFrom<i32> for $name {
|
||||
type Error = Error;
|
||||
type Error = ModeError;
|
||||
|
||||
fn try_from(v: i32) -> Result<Self, Self::Error> {
|
||||
match v {
|
||||
$(x if x == $name::$vname as i32 => Ok($name::$vname),)*
|
||||
_ => Err(Error::BadArgument),
|
||||
_ => Err(ModeError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -704,15 +704,10 @@ fn get_websocket_handshake_error(error: &HandshakeError) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_fs_error(error: &FsOpsError) -> &'static str {
|
||||
fn get_fs_ops_error(error: &FsOpsError) -> &'static str {
|
||||
match error {
|
||||
FsOpsError::Io(e) => get_io_error_class(e),
|
||||
FsOpsError::OperationError(e) => match &e.err {
|
||||
FsError::Io(e) => get_io_error_class(e),
|
||||
FsError::FileBusy => "Busy",
|
||||
FsError::NotSupported => "NotSupported",
|
||||
FsError::NotCapable(_) => "NotCapable",
|
||||
},
|
||||
FsOpsError::OperationError(e) => get_fs_error(&e.err),
|
||||
FsOpsError::Permission(e)
|
||||
| FsOpsError::Resource(e)
|
||||
| FsOpsError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
|
@ -964,6 +959,160 @@ fn get_websocket_upgrade_error(error: &WebSocketUpgradeError) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_fs_error(e: &FsError) -> &'static str {
|
||||
match &e {
|
||||
FsError::Io(e) => get_io_error_class(e),
|
||||
FsError::FileBusy => "Busy",
|
||||
FsError::NotSupported => "NotSupported",
|
||||
FsError::NotCapable(_) => "NotCapable",
|
||||
}
|
||||
}
|
||||
|
||||
mod node {
|
||||
use super::get_error_class_name;
|
||||
use super::get_io_error_class;
|
||||
use super::get_serde_json_error_class;
|
||||
use super::get_url_parse_error_class;
|
||||
pub use deno_node::ops::blocklist::BlocklistError;
|
||||
pub use deno_node::ops::fs::FsError;
|
||||
pub use deno_node::ops::http2::Http2Error;
|
||||
pub use deno_node::ops::idna::IdnaError;
|
||||
pub use deno_node::ops::ipc::IpcError;
|
||||
pub use deno_node::ops::ipc::IpcJsonStreamError;
|
||||
use deno_node::ops::os::priority::PriorityError;
|
||||
pub use deno_node::ops::os::OsError;
|
||||
pub use deno_node::ops::require::RequireError;
|
||||
pub use deno_node::ops::worker_threads::WorkerThreadsFilenameError;
|
||||
pub use deno_node::ops::zlib::brotli::BrotliError;
|
||||
pub use deno_node::ops::zlib::mode::ModeError;
|
||||
pub use deno_node::ops::zlib::ZlibError;
|
||||
|
||||
pub fn get_blocklist_error(error: &BlocklistError) -> &'static str {
|
||||
match error {
|
||||
BlocklistError::AddrParse(_) => "Error",
|
||||
BlocklistError::IpNetwork(_) => "Error",
|
||||
BlocklistError::InvalidAddress => "Error",
|
||||
BlocklistError::IpVersionMismatch => "Error",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_fs_error(error: &FsError) -> &'static str {
|
||||
match error {
|
||||
FsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
FsError::Io(e) => get_io_error_class(e),
|
||||
#[cfg(windows)]
|
||||
FsError::PathHasNoRoot => "Error",
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
FsError::UnsupportedPlatform => "Error",
|
||||
FsError::Fs(e) => super::get_fs_error(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_idna_error(error: &IdnaError) -> &'static str {
|
||||
match error {
|
||||
IdnaError::InvalidInput => "RangeError",
|
||||
IdnaError::InputTooLong => "Error",
|
||||
IdnaError::IllegalInput => "RangeError",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ipc_json_stream_error(error: &IpcJsonStreamError) -> &'static str {
|
||||
match error {
|
||||
IpcJsonStreamError::Io(e) => get_io_error_class(e),
|
||||
IpcJsonStreamError::SimdJson(_) => "Error",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ipc_error(error: &IpcError) -> &'static str {
|
||||
match error {
|
||||
IpcError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
IpcError::IpcJsonStream(e) => get_ipc_json_stream_error(e),
|
||||
IpcError::Canceled(e) => {
|
||||
let io_err: std::io::Error = e.to_owned().into();
|
||||
get_io_error_class(&io_err)
|
||||
}
|
||||
IpcError::SerdeJson(e) => get_serde_json_error_class(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_worker_threads_filename_error(
|
||||
error: &WorkerThreadsFilenameError,
|
||||
) -> &'static str {
|
||||
match error {
|
||||
WorkerThreadsFilenameError::Permission(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
WorkerThreadsFilenameError::UrlParse(e) => get_url_parse_error_class(e),
|
||||
WorkerThreadsFilenameError::InvalidRelativeUrl => "Error",
|
||||
WorkerThreadsFilenameError::UrlFromPathString => "Error",
|
||||
WorkerThreadsFilenameError::UrlToPathString => "Error",
|
||||
WorkerThreadsFilenameError::UrlToPath => "Error",
|
||||
WorkerThreadsFilenameError::FileNotFound(_) => "Error",
|
||||
WorkerThreadsFilenameError::NeitherEsmNorCjs => "Error",
|
||||
WorkerThreadsFilenameError::UrlToNodeResolution(_) => "Error",
|
||||
WorkerThreadsFilenameError::Fs(e) => super::get_fs_error(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_require_error(error: &RequireError) -> &'static str {
|
||||
match error {
|
||||
RequireError::UrlParse(e) => get_url_parse_error_class(e),
|
||||
RequireError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
RequireError::PackageExportsResolve(_) => "Error",
|
||||
RequireError::PackageJsonLoad(_) => "Error",
|
||||
RequireError::ClosestPkgJson(_) => "Error",
|
||||
RequireError::FilePathConversion(_) => "Error",
|
||||
RequireError::PackageImportsResolve(_) => "Error",
|
||||
RequireError::Fs(e) | RequireError::UnableToGetCwd(e) => {
|
||||
super::get_fs_error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_http2_error(error: &Http2Error) -> &'static str {
|
||||
match error {
|
||||
Http2Error::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
Http2Error::UrlParse(e) => get_url_parse_error_class(e),
|
||||
Http2Error::H2(_) => "Error",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_os_error(error: &OsError) -> &'static str {
|
||||
match error {
|
||||
OsError::Priority(e) => match e {
|
||||
PriorityError::Io(e) => get_io_error_class(e),
|
||||
#[cfg(windows)]
|
||||
PriorityError::InvalidPriority => "TypeError",
|
||||
},
|
||||
OsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
OsError::FailedToGetCpuInfo => "TypeError",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_brotli_error(error: &BrotliError) -> &'static str {
|
||||
match error {
|
||||
BrotliError::InvalidEncoderMode => "TypeError",
|
||||
BrotliError::CompressFailed => "TypeError",
|
||||
BrotliError::DecompressFailed => "TypeError",
|
||||
BrotliError::Join(_) => "Error",
|
||||
BrotliError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
BrotliError::Io(e) => get_io_error_class(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mode_error(_: &ModeError) -> &'static str {
|
||||
"Error"
|
||||
}
|
||||
|
||||
pub fn get_zlib_error(e: &ZlibError) -> &'static str {
|
||||
match e {
|
||||
ZlibError::NotInitialized => "TypeError",
|
||||
ZlibError::Mode(e) => get_mode_error(e),
|
||||
ZlibError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_os_error(error: &OsError) -> &'static str {
|
||||
match error {
|
||||
OsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
|
@ -994,6 +1143,46 @@ fn get_sync_fetch_error(error: &SyncFetchError) -> &'static str {
|
|||
|
||||
pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
|
||||
deno_core::error::get_custom_error_class(e)
|
||||
.or_else(|| e.downcast_ref::<FsError>().map(get_fs_error))
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::BlocklistError>()
|
||||
.map(node::get_blocklist_error)
|
||||
})
|
||||
.or_else(|| e.downcast_ref::<node::FsError>().map(node::get_fs_error))
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::IdnaError>()
|
||||
.map(node::get_idna_error)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::IpcJsonStreamError>()
|
||||
.map(node::get_ipc_json_stream_error)
|
||||
})
|
||||
.or_else(|| e.downcast_ref::<node::IpcError>().map(node::get_ipc_error))
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::WorkerThreadsFilenameError>()
|
||||
.map(node::get_worker_threads_filename_error)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::RequireError>()
|
||||
.map(node::get_require_error)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::Http2Error>()
|
||||
.map(node::get_http2_error)
|
||||
})
|
||||
.or_else(|| e.downcast_ref::<node::OsError>().map(node::get_os_error))
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::BrotliError>()
|
||||
.map(node::get_brotli_error)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::ModeError>()
|
||||
.map(node::get_mode_error)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::ZlibError>()
|
||||
.map(node::get_zlib_error)
|
||||
})
|
||||
.or_else(|| e.downcast_ref::<NApiError>().map(get_napi_error_class))
|
||||
.or_else(|| e.downcast_ref::<WebError>().map(get_web_error_class))
|
||||
.or_else(|| {
|
||||
|
@ -1029,7 +1218,7 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
|
|||
e.downcast_ref::<WebSocketUpgradeError>()
|
||||
.map(get_websocket_upgrade_error)
|
||||
})
|
||||
.or_else(|| e.downcast_ref::<FsOpsError>().map(get_fs_error))
|
||||
.or_else(|| e.downcast_ref::<FsOpsError>().map(get_fs_ops_error))
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<DlfcnError>()
|
||||
.map(get_ffi_dlfcn_error_class)
|
||||
|
|
Loading…
Reference in a new issue