Skip to content

Commit d5bcf38

Browse files
authored
fix(arborist): Add better error message when lockfile is malformed (#8268)
Overrides #6997 with a more standard way of expressing errors in the cli and has a test for it.
1 parent f48613d commit d5bcf38

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

workspaces/arborist/lib/arborist/load-virtual.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ module.exports = cls => class VirtualLoader extends cls {
200200
const targetPath = resolve(this.path, meta.resolved)
201201
const targetLoc = relpath(this.path, targetPath)
202202
const target = nodes.get(targetLoc)
203+
204+
if (!target) {
205+
const err = new Error(
206+
`Missing target in lock file: "${targetLoc}" is referenced by "${location}" but does not exist.
207+
To fix:
208+
1. rm package-lock.json
209+
2. npm install`
210+
)
211+
err.code = 'EMISSINGTARGET'
212+
throw err
213+
}
214+
203215
const link = this.#loadLink(location, targetLoc, target, meta)
204216
nodes.set(location, link)
205217
nodes.set(targetLoc, link.target)

workspaces/arborist/test/arborist/load-virtual.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,44 @@ t.test('do not bundle the entire universe', async t => {
245245
'yaml',
246246
].sort())
247247
})
248+
249+
t.test('error when link target is missing', async t => {
250+
const path = t.testdir({
251+
'package.json': JSON.stringify({
252+
name: 'root',
253+
workspaces: ['packages/*'],
254+
}),
255+
'package-lock.json': JSON.stringify({
256+
name: 'root',
257+
lockfileVersion: 3,
258+
packages: {
259+
'': {
260+
workspaces: ['packages/*'],
261+
},
262+
// This is the problematic entry - a link with no corresponding target
263+
'node_modules/@my-scope/my-package': {
264+
resolved: 'packages/some-folder/my-package',
265+
link: true,
266+
},
267+
// Missing entry for 'packages/some-folder/my-package'
268+
},
269+
}),
270+
packages: {
271+
'some-folder': {
272+
'my-package': {
273+
'package.json': JSON.stringify({
274+
name: '@my-scope/my-package',
275+
version: '1.0.0',
276+
}),
277+
},
278+
},
279+
},
280+
})
281+
282+
const arb = new Arborist({ path })
283+
284+
await t.rejects(arb.loadVirtual(), {
285+
code: 'EMISSINGTARGET',
286+
message: /Missing target in lock file:.*but does not exist/,
287+
})
288+
})

0 commit comments

Comments
 (0)