Skip to content

Commit 22230ef

Browse files
committed
fix: make prefixed usage errors more consistent
PR-URL: #3987 Credit: @lukekarrys Close: #3987 Reviewed-by: @wraithgar
1 parent a0d35ff commit 22230ef

File tree

16 files changed

+38
-54
lines changed

16 files changed

+38
-54
lines changed

lib/base-command.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,10 @@ class BaseCommand {
5353
return results
5454
}
5555

56-
usageError (msg) {
57-
if (!msg) {
58-
return Object.assign(new Error(`\nUsage: ${this.usage}`), {
59-
code: 'EUSAGE',
60-
})
61-
}
62-
63-
return Object.assign(new Error(`\nUsage: ${msg}\n\n${this.usage}`), {
56+
usageError (prefix = '') {
57+
if (prefix)
58+
prefix += '\n\n'
59+
return Object.assign(new Error(`\nUsage: ${prefix}${this.usage}`), {
6460
code: 'EUSAGE',
6561
})
6662
}

lib/commands/cache.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class Cache extends BaseCommand {
116116
case 'ls':
117117
return await this.ls(args)
118118
default:
119-
throw Object.assign(new Error(this.usage), { code: 'EUSAGE' })
119+
throw this.usageError()
120120
}
121121
}
122122

@@ -161,14 +161,9 @@ class Cache extends BaseCommand {
161161
// npm cache add <tarball>...
162162
// npm cache add <folder>...
163163
async add (args) {
164-
const usage = 'Usage:\n' +
165-
' npm cache add <tarball-url>...\n' +
166-
' npm cache add <pkg>@<ver>...\n' +
167-
' npm cache add <tarball>...\n' +
168-
' npm cache add <folder>...\n'
169164
log.silly('cache add', 'args', args)
170165
if (args.length === 0)
171-
throw Object.assign(new Error(usage), { code: 'EUSAGE' })
166+
throw this.usageError('First argument to `add` is required')
172167

173168
return Promise.all(args.map(spec => {
174169
log.silly('cache add', 'spec', spec)

lib/commands/diff.js

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,8 @@ class Diff extends BaseCommand {
4949

5050
async exec (args) {
5151
const specs = this.npm.config.get('diff').filter(d => d)
52-
if (specs.length > 2) {
53-
throw new TypeError(
54-
'Can\'t use more than two --diff arguments.\n\n' +
55-
`Usage:\n${this.usage}`
56-
)
57-
}
52+
if (specs.length > 2)
53+
throw this.usageError(`Can't use more than two --diff arguments.`)
5854

5955
// execWorkspaces may have set this already
6056
if (!this.prefix)
@@ -101,7 +97,7 @@ class Diff extends BaseCommand {
10197
}
10298

10399
if (!name)
104-
throw this.usageError('Needs multiple arguments to compare or run from a project dir.\n')
100+
throw this.usageError('Needs multiple arguments to compare or run from a project dir.')
105101

106102
return name
107103
}
@@ -133,7 +129,7 @@ class Diff extends BaseCommand {
133129
noPackageJson = true
134130
}
135131

136-
const missingPackageJson = this.usageError('Needs multiple arguments to compare or run from a project dir.\n')
132+
const missingPackageJson = this.usageError('Needs multiple arguments to compare or run from a project dir.')
137133

138134
// using a valid semver range, that means it should just diff
139135
// the cwd against a published version to the registry using the
@@ -222,7 +218,7 @@ class Diff extends BaseCommand {
222218
`file:${this.prefix}`,
223219
]
224220
} else
225-
throw this.usageError(`Spec type ${spec.type} not supported.\n`)
221+
throw this.usageError(`Spec type ${spec.type} not supported.`)
226222
}
227223

228224
async convertVersionsToSpecs ([a, b]) {
@@ -239,7 +235,7 @@ class Diff extends BaseCommand {
239235
}
240236

241237
if (!pkgName)
242-
throw this.usageError('Needs to be run from a project dir in order to diff two versions.\n')
238+
throw this.usageError('Needs to be run from a project dir in order to diff two versions.')
243239

244240
return [`${pkgName}@${a}`, `${pkgName}@${b}`]
245241
}

lib/commands/edit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Edit extends BaseCommand {
3535

3636
async exec (args) {
3737
if (args.length !== 1)
38-
throw new Error(this.usage)
38+
throw this.usageError()
3939

4040
const path = splitPackageNames(args[0])
4141
const dir = resolve(this.npm.dir, path)

lib/commands/exec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class Exec extends BaseCommand {
8080
const yes = this.npm.config.get('yes')
8181

8282
if (call && _args.length)
83-
throw this.usage
83+
throw this.usageError()
8484

8585
return libexec({
8686
...flatOptions,

lib/commands/explore.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ class Explore extends BaseCommand {
3434

3535
async exec (args) {
3636
if (args.length < 1 || !args[0])
37-
throw this.usage
37+
throw this.usageError()
3838

3939
const pkgname = args.shift()
4040

4141
// detect and prevent any .. shenanigans
4242
const path = join(this.npm.dir, join('/', pkgname))
4343
if (relative(path, this.npm.dir) === '')
44-
throw this.usage
44+
throw this.usageError()
4545

4646
// run as if running a script named '_explore', which we set to either
4747
// the set of arguments, or the shell config, and let @npmcli/run-script

lib/commands/help-search.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class HelpSearch extends BaseCommand {
2828

2929
async exec (args) {
3030
if (!args.length)
31-
return this.npm.output(this.usage)
31+
throw this.usageError()
3232

3333
const docPath = path.resolve(__dirname, '..', '..', 'docs/content')
3434
const files = await glob(`${docPath}/*/*.md`)

lib/commands/hook.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Hook extends BaseCommand {
4343
case 'up':
4444
return this.update(args[1], args[2], args[3], opts)
4545
default:
46-
throw this.usage
46+
throw this.usageError()
4747
}
4848
})
4949
}

lib/commands/pkg.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,7 @@ class Pkg extends BaseCommand {
9696

9797
async set (args) {
9898
const setError = () =>
99-
Object.assign(
100-
new TypeError('npm pkg set expects a key=value pair of args.'),
101-
{ code: 'EPKGSET' }
102-
)
99+
this.usageError('npm pkg set expects a key=value pair of args.')
103100

104101
if (!args.length)
105102
throw setError()
@@ -123,10 +120,7 @@ class Pkg extends BaseCommand {
123120

124121
async delete (args) {
125122
const setError = () =>
126-
Object.assign(
127-
new TypeError('npm pkg delete expects key args.'),
128-
{ code: 'EPKGDELETE' }
129-
)
123+
this.usageError('npm pkg delete expects key args.')
130124

131125
if (!args.length)
132126
throw setError()

lib/commands/profile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class Profile extends BaseCommand {
9090

9191
async exec (args) {
9292
if (args.length === 0)
93-
throw new Error(this.usage)
93+
throw this.usageError()
9494

9595
log.gauge.show('profile')
9696

lib/commands/star.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class Star extends BaseCommand {
3030

3131
async exec (args) {
3232
if (!args.length)
33-
throw new Error(this.usage)
33+
throw this.usageError()
3434

3535
// if we're unstarring, then show an empty star image
3636
// otherwise, show the full star image

lib/commands/team.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class Team extends BaseCommand {
6868
return this.listTeams(entity, opts)
6969
}
7070
default:
71-
throw this.usage
71+
throw this.usageError()
7272
}
7373
})
7474
}

packages/libnpmdiff/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ const formatDiff = require('./lib/format-diff.js')
44
const getTarball = require('./lib/tarball.js')
55
const untar = require('./lib/untar.js')
66

7+
// TODO: we test this condition in the diff command
8+
// so this error probably doesnt need to be here. Or
9+
// if it does we should figure out a standard code
10+
// so we can catch it in the cli and display it consistently
711
const argsError = () =>
812
Object.assign(
913
new TypeError('libnpmdiff needs two arguments to compare'),

test/lib/commands/cache.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ const { fake: mockNpm } = require('../../fixtures/mock-npm.js')
33
const path = require('path')
44
const npa = require('npm-package-arg')
55

6-
const usageUtil = () => 'usage instructions'
7-
86
let outputOutput = []
97

108
let rimrafPath = ''
@@ -140,7 +138,6 @@ const Cache = t.mock('../../../lib/commands/cache.js', {
140138
npmlog,
141139
pacote,
142140
rimraf,
143-
'../../../lib/utils/usage.js': usageUtil,
144141
})
145142

146143
const npm = mockNpm({
@@ -161,7 +158,7 @@ const cache = new Cache(npm)
161158
t.test('cache no args', async t => {
162159
await t.rejects(
163160
cache.exec([]),
164-
'usage instructions',
161+
{ code: 'EUSAGE' },
165162
'should throw usage instructions'
166163
)
167164
})
@@ -194,7 +191,10 @@ t.test('cache add no arg', async t => {
194191

195192
await t.rejects(
196193
cache.exec(['add']),
197-
{ code: 'EUSAGE' },
194+
{
195+
code: 'EUSAGE',
196+
message: 'Usage: First argument to `add` is required',
197+
},
198198
'throws usage error'
199199
)
200200
t.strictSame(logOutput, [

test/lib/commands/help-search.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ t.test('npm help-search long output with color', async t => {
103103
})
104104

105105
t.test('npm help-search no args', async t => {
106-
await helpSearch.exec([])
107-
t.match(OUTPUT, /npm help-search/, 'outputs usage')
106+
t.rejects(helpSearch.exec([]), /npm help-search/, 'outputs usage')
108107
})
109108

110109
t.test('npm help-search no matches', async t => {

test/lib/commands/pkg.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ t.test('set no args', async t => {
196196
})
197197
await t.rejects(
198198
pkg.exec(['set']),
199-
{ code: 'EPKGSET' },
199+
{ code: 'EUSAGE' },
200200
'should throw an error if no args'
201201
)
202202
})
@@ -207,7 +207,7 @@ t.test('set missing value', async t => {
207207
})
208208
await t.rejects(
209209
pkg.exec(['set', 'key=']),
210-
{ code: 'EPKGSET' },
210+
{ code: 'EUSAGE' },
211211
'should throw an error if missing value'
212212
)
213213
})
@@ -218,7 +218,7 @@ t.test('set missing key', async t => {
218218
})
219219
await t.rejects(
220220
pkg.exec(['set', '=value']),
221-
{ code: 'EPKGSET' },
221+
{ code: 'EUSAGE' },
222222
'should throw an error if missing key'
223223
)
224224
})
@@ -424,7 +424,7 @@ t.test('delete no args', async t => {
424424
})
425425
await t.rejects(
426426
pkg.exec(['delete']),
427-
{ code: 'EPKGDELETE' },
427+
{ code: 'EUSAGE' },
428428
'should throw an error if deleting no args'
429429
)
430430
})
@@ -435,7 +435,7 @@ t.test('delete invalid key', async t => {
435435
})
436436
await t.rejects(
437437
pkg.exec(['delete', '']),
438-
{ code: 'EPKGDELETE' },
438+
{ code: 'EUSAGE' },
439439
'should throw an error if deleting invalid args'
440440
)
441441
})

0 commit comments

Comments
 (0)