Skip to content

Commit 1a005b1

Browse files
authored
feat(cmd): enhance error messages with usage examples and guidance
feat(cmd): enhance error messages with usage examples and guidance
2 parents 311a814 + 8e8aee8 commit 1a005b1

6 files changed

Lines changed: 129 additions & 12 deletions

File tree

cmd/decode-es.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,32 @@ func createESDecodeCommand(_ /* alg */, use, short, long, example string, pubKey
2929
}
3030

3131
if privateKeyFile == "" && publicKeyFile == "" {
32-
return fmt.Errorf("private key file or public key file is mandatory\n\n%s", cmd.UsageString())
32+
//nolint:revive,staticcheck // User-facing error message with proper formatting
33+
return fmt.Errorf(`Error: key file is required
34+
35+
Provide either a public key file (recommended) or private key file in PEM format to verify the JWT token.
36+
37+
Example usage with public key (recommended):
38+
jwt-cli decode %s --token "eyJhbGci..." --public-key ./keys/ec-public.pem
39+
40+
Example usage with private key:
41+
jwt-cli decode %s --token "eyJhbGci..." --private-key ./keys/ec-private.pem
42+
43+
Tip: Use the public key for verification to follow asymmetric cryptography best practices.
44+
The key must match the one used to encode the token.
45+
ES256 uses P-256 curve, ES384 uses P-384, ES512 uses P-521.`, use, use)
3346
}
3447
if token == "" {
35-
return fmt.Errorf("token is mandatory\n\n%s", cmd.UsageString())
48+
//nolint:revive,staticcheck // User-facing error message with proper formatting
49+
return fmt.Errorf(`Error: token is required
50+
51+
Provide the JWT token string to decode and verify.
52+
53+
Example usage:
54+
jwt-cli decode %s --token "eyJhbGci..." --public-key ./keys/ec-public.pem
55+
jwt-cli decode %s --token "$TOKEN" --public-key ./keys/ec-public.pem
56+
57+
Tip: The token is the three-part string (header.payload.signature) produced by the encode command.`, use, use)
3658
}
3759

3860
var j cryptojwt.Decoder

cmd/decode-hs.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,28 @@ func createHSDecodeCommand(_ /* alg */, use, short, long, example string, decode
2626
allowWeakSecret, _ := cmd.Flags().GetBool("allow-weak-secret")
2727

2828
if secret == "" {
29-
return fmt.Errorf("secret is mandatory\n\n%s", cmd.UsageString())
29+
//nolint:revive,staticcheck // User-facing error message with proper formatting
30+
return fmt.Errorf(`Error: secret is required
31+
32+
The secret is used to verify the JWT token signature. It must match the secret used for encoding.
33+
34+
Example usage:
35+
jwt-cli decode %s --token "eyJhbGci..." --secret "your-secret-key"
36+
37+
Tip: Use the same secret that was used to encode the token.
38+
HS256 requires at least 32 bytes, HS384 requires 48 bytes, HS512 requires 64 bytes.`, use)
3039
}
3140
if token == "" {
32-
return fmt.Errorf("token is mandatory\n\n%s", cmd.UsageString())
41+
//nolint:revive,staticcheck // User-facing error message with proper formatting
42+
return fmt.Errorf(`Error: token is required
43+
44+
Provide the JWT token string to decode and verify.
45+
46+
Example usage:
47+
jwt-cli decode %s --token "eyJhbGci..." --secret "your-secret-key"
48+
jwt-cli decode %s --token "$TOKEN" --secret "your-secret-key"
49+
50+
Tip: The token is the three-part string (header.payload.signature) produced by the encode command.`, use, use)
3351
}
3452

3553
j := decoderWithOpts([]byte(secret), allowWeakSecret)

cmd/decode-rs.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,31 @@ func createRSDecodeCommand(_ /* alg */, use, short, long, example string, pubKey
2929
}
3030

3131
if privateKeyFile == "" && publicKeyFile == "" {
32-
return fmt.Errorf("private key file or public key file is mandatory\n\n%s", cmd.UsageString())
32+
//nolint:revive,staticcheck // User-facing error message with proper formatting
33+
return fmt.Errorf(`Error: key file is required
34+
35+
Provide either a public key file (recommended) or private key file in PEM format to verify the JWT token.
36+
37+
Example usage with public key (recommended):
38+
jwt-cli decode %s --token "eyJhbGci..." --public-key ./keys/public.pem
39+
40+
Example usage with private key:
41+
jwt-cli decode %s --token "eyJhbGci..." --private-key ./keys/private.pem
42+
43+
Tip: Use the public key for verification to follow asymmetric cryptography best practices.
44+
The key must match the one used to encode the token.`, use, use)
3345
}
3446
if token == "" {
35-
return fmt.Errorf("token is mandatory\n\n%s", cmd.UsageString())
47+
//nolint:revive,staticcheck // User-facing error message with proper formatting
48+
return fmt.Errorf(`Error: token is required
49+
50+
Provide the JWT token string to decode and verify.
51+
52+
Example usage:
53+
jwt-cli decode %s --token "eyJhbGci..." --public-key ./keys/public.pem
54+
jwt-cli decode %s --token "$TOKEN" --public-key ./keys/public.pem
55+
56+
Tip: The token is the three-part string (header.payload.signature) produced by the encode command.`, use, use)
3657
}
3758

3859
var j cryptojwt.Decoder

cmd/encode-es.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,30 @@ func createESEncodeCommand(_ /* alg */, use, short, long, example string, encode
2525
}
2626

2727
if privateKeyFile == "" {
28-
return fmt.Errorf("private key file is mandatory\n\n%s", cmd.UsageString())
28+
//nolint:revive,staticcheck // User-facing error message with proper formatting
29+
return fmt.Errorf(`Error: private key file is required
30+
31+
Provide the path to your ECDSA private key file in PEM format for signing the JWT token.
32+
33+
Example usage:
34+
jwt-cli encode %s --private-key ./keys/ec-private.pem --payload '{"sub":"1234567890","name":"Alice"}'
35+
36+
Generate keys with:
37+
jwt-cli genkeys %s
38+
39+
Tip: ECDSA provides strong security with smaller key sizes compared to RSA.
40+
ES256 uses P-256 curve, ES384 uses P-384, ES512 uses P-521.`, use, use)
2941
}
3042
if payload == "" {
31-
return fmt.Errorf("payload is mandatory\n\n%s", cmd.UsageString())
43+
//nolint:revive,staticcheck // User-facing error message with proper formatting
44+
return fmt.Errorf(`Error: payload is required
45+
46+
The payload contains the claims (data) to be encoded in the JWT token.
47+
48+
Example usage:
49+
jwt-cli encode %s --private-key ./keys/ec-private.pem --payload '{"sub":"1234567890","name":"Alice"}'
50+
51+
Tip: Payload must be valid JSON. Common claims include 'sub' (subject), 'exp' (expiration), 'iat' (issued at).`, use)
3252
}
3353

3454
j := encoder(privateKeyFile)

cmd/encode-hs.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,27 @@ func createHSEncodeCommand(_ /* alg */, use, short, long, example string, encode
2626
allowWeakSecret, _ := cmd.Flags().GetBool("allow-weak-secret")
2727

2828
if secret == "" {
29-
return fmt.Errorf("secret is mandatory\n\n%s", cmd.UsageString())
29+
//nolint:revive,staticcheck // User-facing error message with proper formatting
30+
return fmt.Errorf(`Error: secret is required
31+
32+
The secret is used to sign and verify HMAC-based JWT tokens. It must be kept confidential.
33+
34+
Example usage:
35+
jwt-cli encode %s --secret "your-secret-key" --payload '{"user":"alice","role":"admin"}'
36+
37+
Tip: Use a strong secret. HS256 requires at least 32 bytes, HS384 requires 48 bytes, HS512 requires 64 bytes.
38+
Use --allow-weak-secret flag only for testing purposes.`, use)
3039
}
3140
if payload == "" {
32-
return fmt.Errorf("payload is mandatory\n\n%s", cmd.UsageString())
41+
//nolint:revive,staticcheck // User-facing error message with proper formatting
42+
return fmt.Errorf(`Error: payload is required
43+
44+
The payload contains the claims (data) to be encoded in the JWT token.
45+
46+
Example usage:
47+
jwt-cli encode %s --secret "your-secret-key" --payload '{"user":"alice","role":"admin"}'
48+
49+
Tip: Payload must be valid JSON. Common claims include 'sub' (subject), 'exp' (expiration), 'iat' (issued at).`, use)
3350
}
3451

3552
j := encoderWithOpts([]byte(secret), allowWeakSecret)

cmd/encode-rs.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,29 @@ func createRSEncodeCommand(_ /* alg */, use, short, long, example string, encode
2525
}
2626

2727
if privateKeyFile == "" {
28-
return fmt.Errorf("private key file is mandatory\n\n%s", cmd.UsageString())
28+
//nolint:revive,staticcheck // User-facing error message with proper formatting
29+
return fmt.Errorf(`Error: private key file is required
30+
31+
Provide the path to your RSA private key file in PEM format for signing the JWT token.
32+
33+
Example usage:
34+
jwt-cli encode %s --private-key ./keys/private.pem --payload '{"sub":"1234567890","name":"Alice"}'
35+
36+
Generate keys with:
37+
jwt-cli genkeys %s
38+
39+
Tip: Keep your private key secure and never share it. Use minimum 2048-bit RSA keys.`, use, use)
2940
}
3041
if payload == "" {
31-
return fmt.Errorf("payload is mandatory\n\n%s", cmd.UsageString())
42+
//nolint:revive,staticcheck // User-facing error message with proper formatting
43+
return fmt.Errorf(`Error: payload is required
44+
45+
The payload contains the claims (data) to be encoded in the JWT token.
46+
47+
Example usage:
48+
jwt-cli encode %s --private-key ./keys/private.pem --payload '{"sub":"1234567890","name":"Alice"}'
49+
50+
Tip: Payload must be valid JSON. Common claims include 'sub' (subject), 'exp' (expiration), 'iat' (issued at).`, use)
3251
}
3352

3453
j := encoder(privateKeyFile)

0 commit comments

Comments
 (0)