Skip to content

Commit ae0dbac

Browse files
committed
fix: change ResolveError::NotFound(PathBuf) to report specifier
1 parent 0fdbc75 commit ae0dbac

File tree

11 files changed

+48
-33
lines changed

11 files changed

+48
-33
lines changed

src/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ pub enum ResolveError {
2020
#[error("Path is ignored {0}")]
2121
Ignored(PathBuf),
2222

23-
/// Path not found
24-
#[error("Path not found {0}")]
25-
NotFound(PathBuf),
23+
/// Module not found
24+
#[error("Cannot find module '{0}'")]
25+
NotFound(/* specifier */ String),
2626

2727
/// Tsconfig not found
2828
#[error("Tsconfig not found {0}")]

src/lib.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
250250
if let Some(path) = self.load_as_file_or_directory(&path, specifier, ctx)? {
251251
return Ok(path);
252252
}
253-
Err(ResolveError::NotFound(cached_path.to_path_buf()))
253+
Err(ResolveError::NotFound(specifier.to_string()))
254254
} else {
255255
for root in &self.options.roots {
256256
let cached_path = self.cache.value(root);
@@ -260,7 +260,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
260260
return Ok(path);
261261
}
262262
}
263-
Err(ResolveError::NotFound(cached_path.to_path_buf()))
263+
Err(ResolveError::NotFound(specifier.to_string()))
264264
}
265265
}
266266

@@ -279,7 +279,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
279279
return Ok(path);
280280
}
281281
// c. THROW "not found"
282-
Err(ResolveError::NotFound(path))
282+
Err(ResolveError::NotFound(specifier.to_string()))
283283
}
284284

285285
fn require_hash(
@@ -353,7 +353,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
353353
return Ok(path);
354354
}
355355
// 7. THROW "not found"
356-
Err(ResolveError::NotFound(cached_path.to_path_buf()))
356+
Err(ResolveError::NotFound(specifier.to_string()))
357357
}
358358

359359
/// LOAD_PACKAGE_IMPORTS(X, DIR)
@@ -374,9 +374,9 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
374374
return Ok(None);
375375
}
376376
// 4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE), ["node", "require"]) defined in the ESM resolver.
377-
let path = self.package_imports_resolve(&package_json, specifier, ctx)?;
377+
let path = self.package_imports_resolve(specifier, &package_json, ctx)?;
378378
// 5. RESOLVE_ESM_MATCH(MATCH).
379-
self.resolve_esm_match(&path, &package_json, ctx)
379+
self.resolve_esm_match(specifier, &path, &package_json, ctx)
380380
}
381381

382382
fn load_as_file(&self, cached_path: &CachedPath, ctx: &mut Ctx) -> ResolveResult {
@@ -571,7 +571,9 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
571571
// Try foo/node_modules/package_name
572572
if cached_path.is_dir(&self.cache.fs) {
573573
// a. LOAD_PACKAGE_EXPORTS(X, DIR)
574-
if let Some(path) = self.load_package_exports(subpath, &cached_path, ctx)? {
574+
if let Some(path) =
575+
self.load_package_exports(specifier, subpath, &cached_path, ctx)?
576+
{
575577
return Ok(Some(path));
576578
}
577579
} else {
@@ -620,6 +622,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
620622

621623
fn load_package_exports(
622624
&self,
625+
specifier: &str,
623626
subpath: &str,
624627
cached_path: &CachedPath,
625628
ctx: &mut Ctx,
@@ -646,7 +649,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
646649
ctx,
647650
)? {
648651
// 6. RESOLVE_ESM_MATCH(MATCH)
649-
return self.resolve_esm_match(&path, &package_json, ctx);
652+
return self.resolve_esm_match(specifier, &path, &package_json, ctx);
650653
};
651654
}
652655
Ok(None)
@@ -691,7 +694,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
691694
ctx,
692695
)? {
693696
// 6. RESOLVE_ESM_MATCH(MATCH)
694-
return self.resolve_esm_match(&cached_path, &package_json, ctx);
697+
return self.resolve_esm_match(specifier, &cached_path, &package_json, ctx);
695698
}
696699
}
697700
Ok(None)
@@ -700,24 +703,23 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
700703
/// RESOLVE_ESM_MATCH(MATCH)
701704
fn resolve_esm_match(
702705
&self,
706+
specifier: &str,
703707
cached_path: &CachedPath,
704708
package_json: &PackageJson,
705709
ctx: &mut Ctx,
706710
) -> ResolveResult {
707711
if let Some(path) = self.load_browser_field(cached_path, None, package_json, ctx)? {
708712
return Ok(Some(path));
709713
}
710-
711714
// 1. let RESOLVED_PATH = fileURLToPath(MATCH)
712715
// 2. If the file at RESOLVED_PATH exists, load RESOLVED_PATH as its extension format. STOP
713716
//
714717
// Non-compliant ESM can result in a directory, so directory is tried as well.
715718
if let Some(path) = self.load_as_file_or_directory(cached_path, "", ctx)? {
716719
return Ok(Some(path));
717720
}
718-
719721
// 3. THROW "not found"
720-
Err(ResolveError::NotFound(cached_path.to_path_buf()))
722+
Err(ResolveError::NotFound(specifier.to_string()))
721723
}
722724

723725
/// enhanced-resolve: AliasFieldPlugin for [ResolveOptions::alias_fields]
@@ -743,7 +745,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
743745
return if cached_path.is_file(&self.cache.fs) {
744746
Ok(Some(cached_path.clone()))
745747
} else {
746-
Err(ResolveError::NotFound(cached_path.path().to_path_buf()))
748+
Err(ResolveError::NotFound(new_specifier.to_string()))
747749
};
748750
}
749751
return Err(ResolveError::Recursion);
@@ -1015,7 +1017,7 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
10151017
}
10161018
}
10171019

1018-
Err(ResolveError::NotFound(cached_path.to_path_buf()))
1020+
Err(ResolveError::NotFound(specifier.to_string()))
10191021
}
10201022

10211023
/// PACKAGE_EXPORTS_RESOLVE(packageURL, subpath, exports, conditions)
@@ -1124,8 +1126,8 @@ impl<Fs: FileSystem + Default> ResolverGeneric<Fs> {
11241126
/// PACKAGE_IMPORTS_RESOLVE(specifier, parentURL, conditions)
11251127
fn package_imports_resolve(
11261128
&self,
1127-
package_json: &PackageJson,
11281129
specifier: &str,
1130+
package_json: &PackageJson,
11291131
ctx: &mut Ctx,
11301132
) -> Result<CachedPath, ResolveError> {
11311133
// 1. Assert: specifier begins with "#".

src/tests/browser_field.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ fn recurse_fail() {
8282

8383
#[rustfmt::skip]
8484
let data = [
85-
("recurse non existent", f.clone(), "./lib/non-existent.js", ResolveError::NotFound(f.join("lib/non-existent.js"))),
86-
("path partial match 1", f.clone(), "./xyz.js", ResolveError::NotFound(f.join("xyz.js"))),
87-
("path partial match 2", f.clone(), "./lib/xyz.js", ResolveError::NotFound(f.join("lib/xyz.js"))),
85+
("recurse non existent", f.clone(), "./lib/non-existent.js", ResolveError::NotFound("./lib/non-existent.js".into())),
86+
("path partial match 1", f.clone(), "./xyz.js", ResolveError::NotFound("./xyz.js".into())),
87+
("path partial match 2", f.clone(), "./lib/xyz.js", ResolveError::NotFound("./lib/xyz.js".into())),
8888
];
8989

9090
for (comment, path, request, expected) in data {

src/tests/builtins.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::path::{Path, PathBuf};
1+
use std::path::Path;
22

33
use crate::{ResolveError, ResolveOptions, Resolver};
44

@@ -7,7 +7,7 @@ fn builtins_off() {
77
let f = Path::new("/");
88
let resolver = Resolver::default();
99
let resolved_path = resolver.resolve(f, "zlib").map(|r| r.full_path());
10-
assert_eq!(resolved_path, Err(ResolveError::NotFound(PathBuf::from("/"))));
10+
assert_eq!(resolved_path, Err(ResolveError::NotFound("zlib".into())));
1111
}
1212

1313
#[test]

src/tests/exports_field.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ fn test() {
6363
// ("throw error if extension not provided", f2.clone(), "exports-field/dist/main", ResolveError::NotFound(f2.join("node_modules/exports-field/lib/lib2/main"))),
6464
("resolver should respect query parameters #2. Direct matching", f2.clone(), "exports-field?foo", ResolveError::PackagePathNotExported("./?foo".into(), p2.clone())),
6565
("resolver should respect fragment parameters #2. Direct matching", f2, "exports-field#foo", ResolveError::PackagePathNotExported("./#foo".into(), p2.clone())),
66-
("relative path should not work with exports field", f.clone(), "./node_modules/exports-field/dist/main.js", ResolveError::NotFound(f.join("node_modules/exports-field/dist/main.js"))),
66+
("relative path should not work with exports field", f.clone(), "./node_modules/exports-field/dist/main.js", ResolveError::NotFound("./node_modules/exports-field/dist/main.js".into())),
6767
("backtracking should not work for request", f.clone(), "exports-field/dist/../../../a.js", ResolveError::InvalidPackageTarget("./lib/../../../a.js".to_string(), "/dist/".to_string(), p.clone())),
6868
("backtracking should not work for exports field target", f.clone(), "exports-field/dist/a.js", ResolveError::InvalidPackageTarget("./../../a.js".to_string(), "/dist/a.js".to_string(), p.clone())),
6969
("not exported error", f.clone(), "exports-field/anything/else", ResolveError::PackagePathNotExported("./anything/else".to_string(), p.clone())),

src/tests/extensions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn extensions() {
2929

3030
#[rustfmt::skip]
3131
let fail = [
32-
("not resolve to file when request has a trailing slash (relative)", "./foo.js/", f.join("foo.js"))
32+
("not resolve to file when request has a trailing slash (relative)", "./foo.js/", "./foo.js/".into())
3333
];
3434

3535
for (comment, request, expected_error) in fail {
@@ -93,7 +93,7 @@ fn multi_dot_extension() {
9393

9494
#[rustfmt::skip]
9595
let fail = [
96-
("not resolve to file", "./index.", f.join("index."))
96+
("not resolve to file", "./index.", "./index.".into())
9797
];
9898

9999
for (comment, request, expected_error) in fail {

src/tests/incorrect_description_file.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ fn no_description_file() {
5555
// without description file
5656
let resolver =
5757
Resolver::new(ResolveOptions { description_files: vec![], ..ResolveOptions::default() });
58-
assert_eq!(resolver.resolve(&f, "."), Err(ResolveError::NotFound(f)));
58+
assert_eq!(resolver.resolve(&f, "."), Err(ResolveError::NotFound(".".into())));
5959
}

src/tests/resolve.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! <https://github.com/webpack/enhanced-resolve/blob/main/test/resolve.test.js>
22
3-
use crate::{ResolveOptions, Resolver};
3+
use crate::{ResolveError, ResolveOptions, Resolver};
44

55
#[test]
66
fn resolve() {
@@ -109,3 +109,11 @@ fn resolve_to_context() {
109109
assert_eq!(resolved_path, Ok(expected), "{comment} {path:?} {request}");
110110
}
111111
}
112+
113+
#[test]
114+
fn resolve_hash_as_module() {
115+
let f = super::fixture();
116+
let resolver = Resolver::new(ResolveOptions::default());
117+
let resolution = resolver.resolve(&f, "#a");
118+
assert_eq!(resolution, Err(ResolveError::NotFound("#a".into())));
119+
}

src/tests/roots.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn roots() {
3535

3636
#[rustfmt::skip]
3737
let fail = [
38-
("should not work with relative path", "fixtures/b.js", ResolveError::NotFound(f.clone()))
38+
("should not work with relative path", "fixtures/b.js", ResolveError::NotFound("fixtures/b.js".into()))
3939
];
4040

4141
for (comment, request, expected) in fail {

src/tests/tsconfig_paths.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,11 @@ OneTest {
444444
for test in fail {
445445
let resolved_path =
446446
test.resolver(&root).resolve(&root, test.requested_module).map(|f| f.full_path());
447-
assert_eq!(resolved_path, Err(ResolveError::NotFound("/root".into())), "{}", test.name);
447+
assert_eq!(
448+
resolved_path,
449+
Err(ResolveError::NotFound(test.requested_module.into())),
450+
"{}",
451+
test.name
452+
);
448453
}
449454
}

0 commit comments

Comments
 (0)