Skip to content

Commit

Permalink
fix: throw a meaningful error message on broken lockfile (#4387)
Browse files Browse the repository at this point in the history
When `node-linker` is set to `hoisted`, a meaningful error message
should be thrown if the lockfile is broken and `pnpm install` is
executed.
  • Loading branch information
zkochan committed Feb 24, 2022
1 parent ee797ad commit 7ebe2a0
Show file tree
Hide file tree
Showing 14 changed files with 69 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-books-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pnpm/filter-lockfile": patch
---

Update `@pnpm/error`.
6 changes: 6 additions & 0 deletions .changeset/serious-jars-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@pnpm/real-hoist": patch
"pnpm": patch
---

Throw a meaningful error message on `pnpm install` when the lockfile is broken and `node-linker` is set to `hoisted`.
5 changes: 5 additions & 0 deletions .changeset/stupid-dryers-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pnpm/error": minor
---

Add new error object: LockfileMissingDependencyError.
3 changes: 3 additions & 0 deletions packages/error/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@
"funding": "https://opencollective.com/pnpm",
"devDependencies": {
"@pnpm/error": "workspace:2.0.0"
},
"dependencies": {
"@pnpm/constants": "workspace:5.0.0"
}
}
12 changes: 12 additions & 0 deletions packages/error/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { WANTED_LOCKFILE } from '@pnpm/constants'

export default class PnpmError extends Error {
public readonly code: string
public readonly hint?: string
Expand Down Expand Up @@ -55,3 +57,13 @@ function hideAuthInformation (authHeaderValue: string) {
const [authType, token] = authHeaderValue.split(' ')
return `${authType} ${token.substring(0, 4)}[hidden]`
}

export class LockfileMissingDependencyError extends PnpmError {
constructor (depPath: string) {
const message = `Broken lockfile: no entry for '${depPath}' in ${WANTED_LOCKFILE}`
super('LOCKFILE_MISSING_DEPENDENCY', message, {
hint: 'This issue is probably caused by a badly resolved merge conflict.\n' +
'To fix the lockfile, run \'pnpm install --no-frozen-lockfile\'.',
})
}
}
6 changes: 5 additions & 1 deletion packages/error/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@
"src/**/*.ts",
"../../typings/**/*.d.ts"
],
"references": []
"references": [
{
"path": "../constants"
}
]
}
12 changes: 0 additions & 12 deletions packages/filter-lockfile/src/LockfileMissingDependencyError.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/filter-lockfile/src/filterLockfileByImporters.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { WANTED_LOCKFILE } from '@pnpm/constants'
import { LockfileMissingDependencyError } from '@pnpm/error'
import {
Lockfile,
PackageSnapshots,
Expand All @@ -7,7 +8,6 @@ import lockfileWalker, { LockfileWalkerStep } from '@pnpm/lockfile-walker'
import pnpmLogger from '@pnpm/logger'
import { DependenciesField } from '@pnpm/types'
import filterImporter from './filterImporter'
import LockfileMissingDependencyError from './LockfileMissingDependencyError'

const logger = pnpmLogger('lockfile')

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { WANTED_LOCKFILE } from '@pnpm/constants'
import { LockfileMissingDependencyError } from '@pnpm/error'
import {
Lockfile,
PackageSnapshots,
Expand All @@ -10,7 +11,6 @@ import { DependenciesField } from '@pnpm/types'
import * as dp from 'dependency-path'
import unnest from 'ramda/src/unnest'
import filterImporter from './filterImporter'
import LockfileMissingDependencyError from './LockfileMissingDependencyError'

const logger = pnpmLogger('lockfile')

Expand Down
1 change: 1 addition & 0 deletions packages/real-hoist/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"compile": "tsc --build && pnpm run lint --fix"
},
"dependencies": {
"@pnpm/error": "workspace:2.0.0",
"@pnpm/lockfile-utils": "workspace:3.2.1",
"@yarnpkg/nm": "3.0.1",
"dependency-path": "workspace:8.0.11"
Expand Down
5 changes: 4 additions & 1 deletion packages/real-hoist/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { LockfileMissingDependencyError } from '@pnpm/error'
import {
Lockfile,
nameVerFromPkgSnapshot,
Expand Down Expand Up @@ -70,8 +71,10 @@ function toTree (nodes: Map<string, HoisterTree>, lockfile: Lockfile, deps: Reco
const key = `${alias}:${depPath}`
let node = nodes.get(key)
if (!node) {
// const { name, version, peersSuffix } = nameVerFromPkgSnapshot(depPath, lockfile.packages![depPath])
const pkgSnapshot = lockfile.packages![depPath]
if (!pkgSnapshot) {
throw new LockfileMissingDependencyError(depPath)
}
const pkgName = nameVerFromPkgSnapshot(depPath, pkgSnapshot).name
node = {
name: alias,
Expand Down
17 changes: 17 additions & 0 deletions packages/real-hoist/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,20 @@ test('hoist', async () => {
const lockfile = await readWantedLockfile(path.join(__dirname, '../../..'), { ignoreIncompatible: true })
expect(hoist(lockfile!)).toBeTruthy()
})

test('hoist throws an error if the lockfile is broken', () => {
expect(() => hoist({
lockfileVersion: 5,
importers: {
'.': {
dependencies: {
foo: '1.0.0',
},
specifiers: {
foo: '1.0.0',
},
},
},
packages: {},
})).toThrow(/Broken lockfile/)
})
3 changes: 3 additions & 0 deletions packages/real-hoist/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
{
"path": "../dependency-path"
},
{
"path": "../error"
},
{
"path": "../lockfile-file"
},
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7ebe2a0

Please sign in to comment.