You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(cli): align utils/update/ + utils/command/ error messages with 4-ingredient strategy
Rewrites error messages across packages/cli/src/utils/update/ and
packages/cli/src/utils/command/ to follow the What / Where /
Saw vs. wanted / Fix strategy from CLAUDE.md.
Sources:
- utils/update/checker.mts: 8 messages (URL validation, package name
/ registry URL validation, version-response validation). Each now
names the function, the received type, and what a valid value
looks like.
- utils/update/manager.mts: 3 messages (mirror guards for name /
version / ttl). Still warn-and-return-false, but the text now
tells the caller exactly which option was wrong.
- utils/command/registry-core.mts: 6 messages (command / alias
registration conflicts, middleware next() misuse, flag parsing
failures). Each now names the offending command, flag name, or
index so debuggers don't need to read source.
Tests updated:
- test/unit/utils/update/checker.test.mts: 6 assertions (switched
to regex)
- test/unit/utils/update/manager.test.mts: 3 assertions (switched
to expect.stringContaining)
- test/unit/utils/command/registry-core.test.mts: 5 assertions
All 153 tests in the affected suites pass.
Follows strategy from #1254. Part of the multi-PR series started
by #1255 (commands/) and continued in #1256 (utils/dlx/).
Copy file name to clipboardExpand all lines: packages/cli/src/utils/command/registry-core.mts
+16-6Lines changed: 16 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -24,8 +24,9 @@ export class CommandRegistry implements ICommandRegistry {
24
24
*/
25
25
register(command: CommandDefinition): void{
26
26
if(this.commands.has(command.name)){
27
+
constexisting=this.commands.get(command.name)
27
28
thrownewError(
28
-
`Command "${command.name}" is already registered. Use a unique name or unregister first.`,
29
+
`cannot register command "${command.name}": already registered (existing definition has name="${existing?.name}"); call registry.unregister("${command.name}") first or pick a different name`,
29
30
)
30
31
}
31
32
@@ -36,7 +37,7 @@ export class CommandRegistry implements ICommandRegistry {
36
37
for(constaliasofcommand.aliases){
37
38
if(this.commands.has(alias)){
38
39
thrownewError(
39
-
`Alias "${alias}" conflicts with existing command "${this.commands.get(alias)?.name}"`,
40
+
`cannot register command "${command.name}" alias "${alias}": conflicts with command "${this.commands.get(alias)?.name}"; rename the alias or unregister the conflicting command first`,
40
41
)
41
42
}
42
43
// Store alias pointing to main command.
@@ -221,7 +222,9 @@ export class CommandRegistry implements ICommandRegistry {
221
222
222
223
constdispatch=async(i: number): Promise<void>=>{
223
224
if(i<=index){
224
-
thrownewError('next() called multiple times')
225
+
thrownewError(
226
+
`middleware at index ${index} called next() more than once (each middleware may invoke next() at most once); remove the extra next() call or split the middleware`,
227
+
)
225
228
}
226
229
227
230
index=i
@@ -287,17 +290,22 @@ export class CommandRegistry implements ICommandRegistry {
287
290
}else{
288
291
// --flag value format.
289
292
if(i+1>=args.length){
290
-
thrownewError(`Missing value for flag --${flagName}`)
293
+
thrownewError(
294
+
`flag --${flagName} requires a ${flagDef.type} value but none was provided; pass it as --${flagName}=<value> or --${flagName} <value>`,
295
+
)
291
296
}
292
297
value=args[++i]
293
298
}
294
299
295
300
// Type conversion
296
301
switch(flagDef.type){
297
302
case'number': {
303
+
constraw=value
298
304
value=Number(value)
299
305
if(Number.isNaN(value)){
300
-
thrownewError(`Invalid number value for --${flagName}: ${value}`)
306
+
thrownewError(
307
+
`flag --${flagName} requires a numeric value (saw: "${String(raw)}"); pass an integer or decimal like --${flagName}=42`,
308
+
)
301
309
}
302
310
break
303
311
}
@@ -321,7 +329,9 @@ export class CommandRegistry implements ICommandRegistry {
thrownewError('Package name must be a non-empty string')
210
+
thrownewError(
211
+
`getLatestVersion(name) requires a non-empty string (got: ${typeofname==='string' ? '""' : typeofname}); pass an npm package name like "socket" or "@socketsecurity/cli"`,
212
+
)
209
213
}
210
214
211
215
const{ authInfo, registryUrl =NPM_REGISTRY_URL}={
@@ -214,15 +218,19 @@ const NetworkUtils = {
214
218
}asGetLatestVersionOptions
215
219
216
220
if(!isNonEmptyString(registryUrl)){
217
-
thrownewError('Registry URL must be a non-empty string')
221
+
thrownewError(
222
+
`getLatestVersion options.registryUrl must be a non-empty string (got: ${typeofregistryUrl==='string' ? '""' : typeofregistryUrl}); omit it to default to ${NPM_REGISTRY_URL}`,
thrownewError('Invalid version data in registry response')
252
+
thrownewError(
253
+
`${latestUrl} responded without a .version string (got: ${JSON.stringify(json)?.slice(0,200)??'null'}); the registry may be misconfigured or ${name} may not exist — verify the URL in a browser`,
254
+
)
245
255
}
246
256
247
257
returnjson.version
@@ -284,11 +294,15 @@ async function checkForUpdates(
284
294
}asUpdateCheckOptions
285
295
286
296
if(!isNonEmptyString(name)){
287
-
thrownewError('Package name must be a non-empty string')
297
+
thrownewError(
298
+
`checkForUpdates options.name requires a non-empty string (got: ${typeofname==='string' ? '""' : typeofname}); pass an npm package name like "socket" or "@socketsecurity/cli"`,
299
+
)
288
300
}
289
301
290
302
if(!isNonEmptyString(version)){
291
-
thrownewError('Current version must be a non-empty string')
303
+
thrownewError(
304
+
`checkForUpdates options.version requires a non-empty string (got: ${typeofversion==='string' ? '""' : typeofversion}); pass the currently-installed semver like "1.2.3"`,
305
+
)
292
306
}
293
307
294
308
try{
@@ -298,7 +312,9 @@ async function checkForUpdates(
298
312
})
299
313
300
314
if(!isNonEmptyString(latest)){
301
-
thrownewError('No version information available from registry')
315
+
thrownewError(
316
+
`registry returned no latest version for ${name} (getLatestVersion resolved to ${JSON.stringify(latest)}); check that ${name} exists on ${registryUrl||NPM_REGISTRY_URL}`,
0 commit comments