diff --git a/cli/resolver.rs b/cli/resolver.rs index 7b8766ee99..6049ec2732 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -24,6 +24,8 @@ use deno_npm::resolution::NpmResolutionError; use deno_runtime::deno_fs; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::errors::ClosestPkgJsonError; +use deno_runtime::deno_node::errors::NodeResolveError; +use deno_runtime::deno_node::errors::ResolvePkgSubpathFromDenoModuleError; use deno_runtime::deno_node::errors::UrlToNodeResolutionError; use deno_runtime::deno_node::is_builtin_node_module; use deno_runtime::deno_node::parse_npm_pkg_name; @@ -105,7 +107,7 @@ impl CliNodeResolver { specifier: &str, referrer: &ModuleSpecifier, mode: NodeResolutionMode, - ) -> Option, AnyError>> { + ) -> Option, NodeResolveError>> { if self.in_npm_package(referrer) { // we're in an npm package, so use node resolution Some(self.resolve(specifier, referrer, mode)) @@ -119,19 +121,18 @@ impl CliNodeResolver { specifier: &str, referrer: &ModuleSpecifier, mode: NodeResolutionMode, - ) -> Result, AnyError> { + ) -> Result, NodeResolveError> { let referrer_kind = if self.cjs_resolutions.contains(referrer) { NodeModuleKind::Cjs } else { NodeModuleKind::Esm }; - self.handle_node_resolve_result( + let maybe_res = self .node_resolver - .resolve(specifier, referrer, referrer_kind, mode) - .map_err(AnyError::from), - ) + .resolve(specifier, referrer, referrer_kind, mode)?; + Ok(self.handle_node_resolution(maybe_res)) } pub fn resolve_req_reference( @@ -218,18 +219,16 @@ impl CliNodeResolver { sub_path: Option<&str>, maybe_referrer: Option<&ModuleSpecifier>, mode: NodeResolutionMode, - ) -> Result, AnyError> { - self.handle_node_resolve_result( - self - .node_resolver - .resolve_package_subpath_from_deno_module( - package_folder, - sub_path, - maybe_referrer, - mode, - ) - .map_err(AnyError::from), - ) + ) -> Result, ResolvePkgSubpathFromDenoModuleError> { + let maybe_res = self + .node_resolver + .resolve_package_subpath_from_deno_module( + package_folder, + sub_path, + maybe_referrer, + mode, + )?; + Ok(self.handle_node_resolution(maybe_res)) } pub fn handle_if_in_node_modules( @@ -266,20 +265,15 @@ impl CliNodeResolver { self.node_resolver.url_to_node_resolution(specifier) } - fn handle_node_resolve_result( + fn handle_node_resolution( &self, - result: Result, AnyError>, - ) -> Result, AnyError> { - match result? { - Some(response) => { - if let NodeResolution::CommonJs(specifier) = &response { - // remember that this was a common js resolution - self.cjs_resolutions.insert(specifier.clone()); - } - Ok(Some(response)) - } - None => Ok(None), + maybe_resolution: Option, + ) -> Option { + if let Some(NodeResolution::CommonJs(specifier)) = &maybe_resolution { + // remember that this was a common js resolution + self.cjs_resolutions.insert(specifier.clone()); } + maybe_resolution } } @@ -465,7 +459,7 @@ impl CliGraphResolver { } } - // todo(dsherret): if we returned structured errors from the NodeResolver we wouldn't need this + // todo(dsherret): update this and the surrounding code to handle the structured errors from NodeResolver fn check_surface_byonm_node_error( &self, specifier: &str, @@ -681,7 +675,10 @@ impl Resolver for CliGraphResolver { Err(err) => { self .check_surface_byonm_node_error( - specifier, referrer, err, resolver, + specifier, + referrer, + err.into(), + resolver, ) .map_err(ResolveError::Other)?; } diff --git a/ext/node/errors.rs b/ext/node/errors.rs index 560336d68c..98b207e86a 100644 --- a/ext/node/errors.rs +++ b/ext/node/errors.rs @@ -1,10 +1,9 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use std::borrow::Cow; +use std::fmt::Write; use std::path::PathBuf; -use deno_core::error::generic_error; -use deno_core::error::AnyError; use deno_core::ModuleSpecifier; use thiserror::Error; @@ -38,11 +37,62 @@ macro_rules! kinded_err { }; } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[allow(non_camel_case_types)] +pub enum NodeJsErrorCode { + ERR_INVALID_MODULE_SPECIFIER, + ERR_INVALID_PACKAGE_CONFIG, + ERR_INVALID_PACKAGE_TARGET, + ERR_MODULE_NOT_FOUND, + ERR_PACKAGE_IMPORT_NOT_DEFINED, + ERR_PACKAGE_PATH_NOT_EXPORTED, + ERR_UNKNOWN_FILE_EXTENSION, + ERR_UNSUPPORTED_DIR_IMPORT, + ERR_UNSUPPORTED_ESM_URL_SCHEME, +} + +impl std::fmt::Display for NodeJsErrorCode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl NodeJsErrorCode { + pub fn as_str(&self) -> &'static str { + use NodeJsErrorCode::*; + match self { + ERR_INVALID_MODULE_SPECIFIER => "ERR_INVALID_MODULE_SPECIFIER", + ERR_INVALID_PACKAGE_CONFIG => "ERR_INVALID_PACKAGE_CONFIG", + ERR_INVALID_PACKAGE_TARGET => "ERR_INVALID_PACKAGE_TARGET", + ERR_MODULE_NOT_FOUND => "ERR_MODULE_NOT_FOUND", + ERR_PACKAGE_IMPORT_NOT_DEFINED => "ERR_PACKAGE_IMPORT_NOT_DEFINED", + ERR_PACKAGE_PATH_NOT_EXPORTED => "ERR_PACKAGE_PATH_NOT_EXPORTED", + ERR_UNKNOWN_FILE_EXTENSION => "ERR_UNKNOWN_FILE_EXTENSION", + ERR_UNSUPPORTED_DIR_IMPORT => "ERR_UNSUPPORTED_DIR_IMPORT", + ERR_UNSUPPORTED_ESM_URL_SCHEME => "ERR_UNSUPPORTED_ESM_URL_SCHEME", + } + } +} + +pub trait NodeJsErrorCoded { + fn code(&self) -> NodeJsErrorCode; +} + kinded_err!( ResolvePkgSubpathFromDenoModuleError, ResolvePkgSubpathFromDenoModuleErrorKind ); +impl NodeJsErrorCoded for ResolvePkgSubpathFromDenoModuleError { + fn code(&self) -> NodeJsErrorCode { + use ResolvePkgSubpathFromDenoModuleErrorKind::*; + match self.as_kind() { + PackageSubpathResolve(e) => e.code(), + UrlToNodeResolution(e) => e.code(), + } + } +} + #[derive(Debug, Error)] pub enum ResolvePkgSubpathFromDenoModuleErrorKind { #[error(transparent)] @@ -54,7 +104,8 @@ pub enum ResolvePkgSubpathFromDenoModuleErrorKind { // todo(https://github.com/denoland/deno_core/issues/810): make this a TypeError #[derive(Debug, Clone, Error)] #[error( - "[ERR_INVALID_MODULE_SPECIFIER] Invalid module '{}' {}{}", + "[{}] Invalid module '{}' {}{}", + self.code(), request, reason, maybe_referrer.as_ref().map(|referrer| format!(" imported from '{}'", referrer)).unwrap_or_default() @@ -65,14 +116,40 @@ pub struct InvalidModuleSpecifierError { pub maybe_referrer: Option, } +impl NodeJsErrorCoded for InvalidModuleSpecifierError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_INVALID_MODULE_SPECIFIER + } +} + #[derive(Debug, Error)] pub enum LegacyMainResolveError { #[error(transparent)] PathToDeclarationUrl(PathToDeclarationUrlError), } +impl NodeJsErrorCoded for LegacyMainResolveError { + fn code(&self) -> NodeJsErrorCode { + match self { + Self::PathToDeclarationUrl(e) => e.code(), + } + } +} + kinded_err!(PackageFolderResolveError, PackageFolderResolveErrorKind); +impl NodeJsErrorCoded for PackageFolderResolveError { + fn code(&self) -> NodeJsErrorCode { + match self.as_kind() { + PackageFolderResolveErrorKind::NotFoundPackage { .. } + | PackageFolderResolveErrorKind::NotFoundReferrer { .. } + | PackageFolderResolveErrorKind::Io { .. } => { + NodeJsErrorCode::ERR_MODULE_NOT_FOUND + } + } + } +} + #[derive(Debug, Error)] pub enum PackageFolderResolveErrorKind { #[error( @@ -108,15 +185,25 @@ pub enum PackageFolderResolveErrorKind { kinded_err!(PackageSubpathResolveError, PackageSubpathResolveErrorKind); +impl NodeJsErrorCoded for PackageSubpathResolveError { + fn code(&self) -> NodeJsErrorCode { + match self.as_kind() { + PackageSubpathResolveErrorKind::PkgJsonLoad(e) => e.code(), + PackageSubpathResolveErrorKind::PackageFolderResolve(e) => e.code(), + PackageSubpathResolveErrorKind::Exports(e) => e.code(), + PackageSubpathResolveErrorKind::LegacyMain(e) => e.code(), + PackageSubpathResolveErrorKind::LegacyExact(e) => e.code(), + } + } +} + #[derive(Debug, Error)] pub enum PackageSubpathResolveErrorKind { #[error(transparent)] - PkgJsonLoad(#[from] deno_config::package_json::PackageJsonLoadError), + PkgJsonLoad(#[from] PackageJsonLoadError), #[error(transparent)] PackageFolderResolve(#[from] PackageFolderResolveError), #[error(transparent)] - DirNotFound(AnyError), - #[error(transparent)] Exports(PackageExportsResolveError), #[error(transparent)] LegacyMain(LegacyMainResolveError), @@ -152,8 +239,26 @@ pub struct PackageTargetNotFoundError { pub mode: NodeResolutionMode, } +impl NodeJsErrorCoded for PackageTargetNotFoundError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_MODULE_NOT_FOUND + } +} + kinded_err!(PackageTargetResolveError, PackageTargetResolveErrorKind); +impl NodeJsErrorCoded for PackageTargetResolveError { + fn code(&self) -> NodeJsErrorCode { + match self.as_kind() { + PackageTargetResolveErrorKind::NotFound(e) => e.code(), + PackageTargetResolveErrorKind::InvalidPackageTarget(e) => e.code(), + PackageTargetResolveErrorKind::InvalidModuleSpecifier(e) => e.code(), + PackageTargetResolveErrorKind::PackageResolve(e) => e.code(), + PackageTargetResolveErrorKind::PathToDeclarationUrl(e) => e.code(), + } + } +} + #[derive(Debug, Error)] pub enum PackageTargetResolveErrorKind { #[error(transparent)] @@ -170,6 +275,15 @@ pub enum PackageTargetResolveErrorKind { kinded_err!(PackageExportsResolveError, PackageExportsResolveErrorKind); +impl NodeJsErrorCoded for PackageExportsResolveError { + fn code(&self) -> NodeJsErrorCode { + match self.as_kind() { + PackageExportsResolveErrorKind::PackagePathNotExported(e) => e.code(), + PackageExportsResolveErrorKind::PackageTargetResolve(e) => e.code(), + } + } +} + #[derive(Debug, Error)] pub enum PackageExportsResolveErrorKind { #[error(transparent)] @@ -184,18 +298,63 @@ pub enum PathToDeclarationUrlError { SubPath(#[from] PackageSubpathResolveError), } +impl NodeJsErrorCoded for PathToDeclarationUrlError { + fn code(&self) -> NodeJsErrorCode { + match self { + PathToDeclarationUrlError::SubPath(e) => e.code(), + } + } +} + +#[derive(Debug, Error)] +#[error( + "[{}] Invalid package config. {}", + self.code(), + self.0 +)] +pub struct PackageJsonLoadError( + #[source] + #[from] + pub deno_config::package_json::PackageJsonLoadError, +); + +impl NodeJsErrorCoded for PackageJsonLoadError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_INVALID_PACKAGE_CONFIG + } +} + kinded_err!(ClosestPkgJsonError, ClosestPkgJsonErrorKind); +impl NodeJsErrorCoded for ClosestPkgJsonError { + fn code(&self) -> NodeJsErrorCode { + match self.as_kind() { + ClosestPkgJsonErrorKind::CanonicalizingDir(e) => e.code(), + ClosestPkgJsonErrorKind::Load(e) => e.code(), + } + } +} + #[derive(Debug, Error)] pub enum ClosestPkgJsonErrorKind { - #[error("Failed canonicalizing package.json directory '{dir_path}'.")] - CanonicalizingDir { - dir_path: PathBuf, - #[source] - source: std::io::Error, - }, #[error(transparent)] - Load(#[from] deno_config::package_json::PackageJsonLoadError), + CanonicalizingDir(#[from] CanonicalizingPkgJsonDirError), + #[error(transparent)] + Load(#[from] PackageJsonLoadError), +} + +#[derive(Debug, Error)] +#[error("[{}] Failed canonicalizing package.json directory '{}'.", self.code(), dir_path.display())] +pub struct CanonicalizingPkgJsonDirError { + pub dir_path: PathBuf, + #[source] + pub source: std::io::Error, +} + +impl NodeJsErrorCoded for CanonicalizingPkgJsonDirError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_MODULE_NOT_FOUND + } } #[derive(Debug, Error)] @@ -204,8 +363,23 @@ pub struct TypeScriptNotSupportedInNpmError { pub specifier: ModuleSpecifier, } +impl NodeJsErrorCoded for TypeScriptNotSupportedInNpmError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_UNKNOWN_FILE_EXTENSION + } +} + kinded_err!(UrlToNodeResolutionError, UrlToNodeResolutionErrorKind); +impl NodeJsErrorCoded for UrlToNodeResolutionError { + fn code(&self) -> NodeJsErrorCode { + match self.as_kind() { + UrlToNodeResolutionErrorKind::TypeScriptNotSupported(e) => e.code(), + UrlToNodeResolutionErrorKind::ClosestPkgJson(e) => e.code(), + } + } +} + #[derive(Debug, Error)] pub enum UrlToNodeResolutionErrorKind { #[error(transparent)] @@ -217,7 +391,8 @@ pub enum UrlToNodeResolutionErrorKind { // todo(https://github.com/denoland/deno_core/issues/810): make this a TypeError #[derive(Debug, Error)] #[error( - "[ERR_PACKAGE_IMPORT_NOT_DEFINED] Package import specifier \"{}\" is not defined{}{}", + "[{}] Package import specifier \"{}\" is not defined{}{}", + self.code(), name, package_json_path.as_ref().map(|p| format!(" in package {}", p.display())).unwrap_or_default(), maybe_referrer.as_ref().map(|r| format!(" imported from '{}'", r)).unwrap_or_default(), @@ -228,6 +403,12 @@ pub struct PackageImportNotDefinedError { pub maybe_referrer: Option, } +impl NodeJsErrorCoded for PackageImportNotDefinedError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_PACKAGE_IMPORT_NOT_DEFINED + } +} + kinded_err!(PackageImportsResolveError, PackageImportsResolveErrorKind); #[derive(Debug, Error)] @@ -242,8 +423,30 @@ pub enum PackageImportsResolveErrorKind { Target(#[from] PackageTargetResolveError), } +impl NodeJsErrorCoded for PackageImportsResolveErrorKind { + fn code(&self) -> NodeJsErrorCode { + match self { + Self::ClosestPkgJson(e) => e.code(), + Self::InvalidModuleSpecifier(e) => e.code(), + Self::NotDefined(e) => e.code(), + Self::Target(e) => e.code(), + } + } +} + kinded_err!(PackageResolveError, PackageResolveErrorKind); +impl NodeJsErrorCoded for PackageResolveError { + fn code(&self) -> NodeJsErrorCode { + match self.as_kind() { + PackageResolveErrorKind::ClosestPkgJson(e) => e.code(), + PackageResolveErrorKind::InvalidModuleSpecifier(e) => e.code(), + PackageResolveErrorKind::ExportsResolve(e) => e.code(), + PackageResolveErrorKind::SubpathResolve(e) => e.code(), + } + } +} + #[derive(Debug, Error)] pub enum PackageResolveErrorKind { #[error(transparent)] @@ -298,7 +501,8 @@ pub enum FinalizeResolutionErrorKind { #[derive(Debug, Error)] #[error( - "[ERR_MODULE_NOT_FOUND] Cannot find {} '{}'{}", + "[{}] Cannot find {} '{}'{}", + self.code(), typ, specifier, maybe_referrer.as_ref().map(|referrer| format!(" imported from '{}'", referrer)).unwrap_or_default() @@ -309,9 +513,16 @@ pub struct ModuleNotFoundError { pub typ: &'static str, } +impl ModuleNotFoundError { + pub fn code(&self) -> &'static str { + "ERR_MODULE_NOT_FOUND" + } +} + #[derive(Debug, Error)] #[error( - "[ERR_UNSUPPORTED_DIR_IMPORT] Directory import '{}' is not supported resolving ES modules{}", + "[{}] Directory import '{}' is not supported resolving ES modules{}", + self.code(), dir_url, maybe_referrer.as_ref().map(|referrer| format!(" imported from '{}'", referrer)).unwrap_or_default(), )] @@ -320,6 +531,12 @@ pub struct UnsupportedDirImportError { pub maybe_referrer: Option, } +impl NodeJsErrorCoded for UnsupportedDirImportError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_UNSUPPORTED_DIR_IMPORT + } +} + #[derive(Debug)] pub struct InvalidPackageTargetError { pub pkg_json_path: PathBuf, @@ -336,7 +553,9 @@ impl std::fmt::Display for InvalidPackageTargetError { let rel_error = !self.is_import && !self.target.is_empty() && !self.target.starts_with("./"); - f.write_str("[ERR_INVALID_PACKAGE_TARGET]")?; + f.write_char('[')?; + f.write_str(self.code().as_str())?; + f.write_char(']')?; if self.sub_path == "." { assert!(!self.is_import); @@ -368,6 +587,12 @@ impl std::fmt::Display for InvalidPackageTargetError { } } +impl NodeJsErrorCoded for InvalidPackageTargetError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_INVALID_PACKAGE_TARGET + } +} + #[derive(Debug)] pub struct PackagePathNotExportedError { pub pkg_json_path: PathBuf, @@ -376,11 +601,19 @@ pub struct PackagePathNotExportedError { pub mode: NodeResolutionMode, } +impl NodeJsErrorCoded for PackagePathNotExportedError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_PACKAGE_PATH_NOT_EXPORTED + } +} + impl std::error::Error for PackagePathNotExportedError {} impl std::fmt::Display for PackagePathNotExportedError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("[ERR_PACKAGE_PATH_NOT_EXPORTED]")?; + f.write_char('[')?; + f.write_str(self.code().as_str())?; + f.write_char(']')?; let types_msg = match self.mode { NodeResolutionMode::Execution => String::new(), @@ -412,7 +645,8 @@ impl std::fmt::Display for PackagePathNotExportedError { #[derive(Debug, Clone, Error)] #[error( - "[ERR_UNSUPPORTED_ESM_URL_SCHEME] Only file and data URLS are supported by the default ESM loader.{} Received protocol '{}'", + "[{}] Only file and data URLs are supported by the default ESM loader.{} Received protocol '{}'", + self.code(), if cfg!(windows) && url_scheme.len() == 2 { " On Windows, absolute path must be valid file:// URLS."} else { "" }, url_scheme )] @@ -420,10 +654,16 @@ pub struct UnsupportedEsmUrlSchemeError { pub url_scheme: String, } +impl NodeJsErrorCoded for UnsupportedEsmUrlSchemeError { + fn code(&self) -> NodeJsErrorCode { + NodeJsErrorCode::ERR_UNSUPPORTED_ESM_URL_SCHEME + } +} + #[derive(Debug, Error)] pub enum ResolvePkgJsonBinExportError { #[error(transparent)] - PkgJsonLoad(#[from] deno_config::package_json::PackageJsonLoadError), + PkgJsonLoad(#[from] PackageJsonLoadError), #[error("Failed resolving binary export. '{}' did not exist", pkg_json_path.display())] MissingPkgJson { pkg_json_path: PathBuf }, #[error("Failed resolving binary export. {message}")] @@ -435,31 +675,11 @@ pub enum ResolvePkgJsonBinExportError { #[derive(Debug, Error)] pub enum ResolveBinaryCommandsError { #[error(transparent)] - PkgJsonLoad(#[from] deno_config::package_json::PackageJsonLoadError), + PkgJsonLoad(#[from] PackageJsonLoadError), #[error("'{}' did not have a name", pkg_json_path.display())] MissingPkgJsonName { pkg_json_path: PathBuf }, } -#[allow(unused)] -pub fn err_invalid_package_config( - path: &str, - maybe_base: Option, - maybe_message: Option, -) -> AnyError { - let mut msg = - format!("[ERR_INVALID_PACKAGE_CONFIG] Invalid package config {path}"); - - if let Some(base) = maybe_base { - msg = format!("{msg} while importing {base}"); - } - - if let Some(message) = maybe_message { - msg = format!("{msg}. {message}"); - } - - generic_error(msg) -} - #[cfg(test)] mod test { use super::*; diff --git a/ext/node/package_json.rs b/ext/node/package_json.rs index 8a88fe8f10..b28207db8b 100644 --- a/ext/node/package_json.rs +++ b/ext/node/package_json.rs @@ -1,7 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use deno_config::package_json::PackageJson; -use deno_config::package_json::PackageJsonLoadError; use deno_config::package_json::PackageJsonRc; use deno_fs::DenoConfigFsAdapter; use std::cell::RefCell; @@ -10,6 +9,8 @@ use std::io::ErrorKind; use std::path::Path; use std::path::PathBuf; +use crate::errors::PackageJsonLoadError; + // use a thread local cache so that workers have their own distinct cache thread_local! { static CACHE: RefCell> = RefCell::new(HashMap::new()); @@ -48,11 +49,9 @@ pub fn load_pkg_json( ); match result { Ok(pkg_json) => Ok(Some(pkg_json)), - Err(PackageJsonLoadError::Io { source, .. }) - if source.kind() == ErrorKind::NotFound => - { - Ok(None) - } - Err(err) => Err(err), + Err(deno_config::package_json::PackageJsonLoadError::Io { + source, .. + }) if source.kind() == ErrorKind::NotFound => Ok(None), + Err(err) => Err(PackageJsonLoadError(err)), } } diff --git a/ext/node/resolution.rs b/ext/node/resolution.rs index 84d8ba39dd..cf30305a9f 100644 --- a/ext/node/resolution.rs +++ b/ext/node/resolution.rs @@ -16,18 +16,21 @@ use deno_fs::FileSystemRc; use deno_media_type::MediaType; use crate::errors; +use crate::errors::CanonicalizingPkgJsonDirError; use crate::errors::ClosestPkgJsonError; -use crate::errors::ClosestPkgJsonErrorKind; use crate::errors::FinalizeResolutionError; use crate::errors::InvalidModuleSpecifierError; use crate::errors::InvalidPackageTargetError; use crate::errors::LegacyMainResolveError; use crate::errors::ModuleNotFoundError; +use crate::errors::NodeJsErrorCode; +use crate::errors::NodeJsErrorCoded; use crate::errors::NodeResolveError; use crate::errors::PackageExportsResolveError; use crate::errors::PackageImportNotDefinedError; use crate::errors::PackageImportsResolveError; use crate::errors::PackageImportsResolveErrorKind; +use crate::errors::PackageJsonLoadError; use crate::errors::PackagePathNotExportedError; use crate::errors::PackageResolveError; use crate::errors::PackageSubpathResolveError; @@ -283,7 +286,7 @@ impl NodeResolver { let maybe_url = if mode.is_types() { let file_path = to_file_path(&url); - self.path_to_declaration_url(file_path, Some(referrer), referrer_kind)? + self.path_to_declaration_url(&file_path, Some(referrer), referrer_kind)? } else { Some(url) }; @@ -469,7 +472,7 @@ impl NodeResolver { /// Checks if the resolved file has a corresponding declaration file. fn path_to_declaration_url( &self, - path: PathBuf, + path: &Path, maybe_referrer: Option<&ModuleSpecifier>, referrer_kind: NodeModuleKind, ) -> Result, PathToDeclarationUrlError> { @@ -522,16 +525,16 @@ impl NodeResolver { || lowercase_path.ends_with(".d.cts") || lowercase_path.ends_with(".d.mts") { - return Ok(Some(to_file_specifier(&path))); + return Ok(Some(to_file_specifier(path))); } if let Some(path) = - probe_extensions(&*self.fs, &path, &lowercase_path, referrer_kind) + probe_extensions(&*self.fs, path, &lowercase_path, referrer_kind) { return Ok(Some(to_file_specifier(&path))); } - if self.fs.is_dir_sync(&path) { + if self.fs.is_dir_sync(path) { let maybe_resolution = self.resolve_package_dir_subpath( - &path, + path, /* sub path */ ".", maybe_referrer, referrer_kind, @@ -556,7 +559,7 @@ impl NodeResolver { } // allow resolving .css files for types resolution if lowercase_path.ends_with(".css") { - return Ok(Some(to_file_specifier(&path))); + return Ok(Some(to_file_specifier(path))); } Ok(None) } @@ -845,7 +848,7 @@ impl NodeResolver { if mode.is_types() && url.scheme() == "file" { let path = url.to_file_path().unwrap(); return Ok(self.path_to_declaration_url( - path, + &path, maybe_referrer, referrer_kind, )?); @@ -879,8 +882,7 @@ impl NodeResolver { continue; } Err(e) => { - // todo(dsherret): add codes to each error and match on that instead - if e.to_string().starts_with("[ERR_INVALID_PACKAGE_TARGET]") { + if e.code() == NodeJsErrorCode::ERR_INVALID_PACKAGE_TARGET { last_error = Some(e); continue; } else { @@ -1274,7 +1276,7 @@ impl NodeResolver { assert_ne!(package_subpath, "."); let file_path = directory.join(package_subpath); if mode.is_types() { - Ok(self.path_to_declaration_url(file_path, referrer, referrer_kind)?) + Ok(self.path_to_declaration_url(&file_path, referrer, referrer_kind)?) } else { Ok(Some(to_file_specifier(&file_path))) } @@ -1318,7 +1320,7 @@ impl NodeResolver { let parent_dir = file_path.parent().unwrap(); let current_dir = deno_core::strip_unc_prefix(self.fs.realpath_sync(parent_dir).map_err( - |source| ClosestPkgJsonErrorKind::CanonicalizingDir { + |source| CanonicalizingPkgJsonDirError { dir_path: parent_dir.to_path_buf(), source: source.into_io_error(), }, @@ -1336,10 +1338,7 @@ impl NodeResolver { pub(super) fn load_package_json( &self, package_json_path: &Path, - ) -> Result< - Option, - deno_config::package_json::PackageJsonLoadError, - > { + ) -> Result, PackageJsonLoadError> { crate::package_json::load_pkg_json(&*self.fs, package_json_path) } @@ -1359,7 +1358,7 @@ impl NodeResolver { if let Some(main) = package_json.main(referrer_kind) { let main = package_json.path.parent().unwrap().join(main).clean(); let maybe_decl_url = self - .path_to_declaration_url(main, maybe_referrer, referrer_kind) + .path_to_declaration_url(&main, maybe_referrer, referrer_kind) .map_err(LegacyMainResolveError::PathToDeclarationUrl)?; if let Some(path) = maybe_decl_url { return Ok(Some(path));