Skip to content

Conversation

@vroldanbet
Copy link
Contributor

@vroldanbet vroldanbet commented Apr 23, 2025

Built on top of #492

The usage was being printed on any error, which was rather unpleasant to look at because it made the output difficult to parse for clues on what happened. The primary goal of this commit is to enhance the user experience.

Cobra supports SilenceErrors and SilenceUsage, as well as a callback function, SetFlagErrorFunc, for handling flag parsing errors and controlling when usage and errors are printed. Unfortunately, only a subset of errors fall under the "flag parsing error" category: validation errors defined via Command.Args do not trigger FlagErrorFunc, so if SilenceUsage is enabled, we would miss the usage for those validation cases 😢

To address this, a special error wrapper is introduced that signals an error is a validation error, allowing the command to manually print the usage when SilenceUsage is enabled, which this commit does.

A few tests are added that assert the output. Due to the pervasive use of globals, some refactoring was conducted in cmd.go to make it more test-friendly.

This is what the command line output looked like when a normal application error happened:

```shell
$ zed preview schema compile root.zed
Usage:
  zed preview schema compile <file> [flags]

Examples:

        Write to stdout:
                zed preview schema compile root.zed
        Write to an output file:
                zed preview schema compile --out compiled.zed
        

Flags:
  -h, --help         help for compile
      --out string   output filepath; omitting writes to stdout

Global Flags:
      --certificate-path string     path to certificate authority used to verify secure connections
      --endpoint string             spicedb gRPC API endpoint
      --hostname-override string    override the hostname used in the connection to the endpoint
      --insecure                    connect over a plaintext connection
      --log-format string           format of logs ("auto", "console", "json") (default "auto")
      --log-level string            verbosity of logging ("trace", "debug", "info", "warn", "error") (default "info")
      --max-message-size int        maximum size *in bytes* (defaults to 4_194_304 bytes ~= 4MB) of a gRPC message that can be sent or received by zed
      --no-verify-ca                do not attempt to verify the server's certificate chain and host name
      --permissions-system string   permissions system to query
      --request-id string           optional id to send along with SpiceDB requests for tracing
      --skip-version-check          if true, no version check is performed against the server
      --token string                token used to authenticate to SpiceDB

3:29PM ERR terminated with errors error="failed to read schema file: open root.zed: no such file or directory"

This is what it looks like now after the change

```shell
$ zed preview schema compile root.zed
3:29PM ERR terminated with errors error="failed to read schema file: open root.zed: no such file or directory"

@vroldanbet vroldanbet changed the title print usage only on validation errors print usage only on parse/validation errors Apr 23, 2025
@vroldanbet vroldanbet requested a review from josephschorr April 23, 2025 14:09
@vroldanbet vroldanbet self-assigned this Apr 23, 2025
@vroldanbet vroldanbet requested a review from tstirrat15 April 23, 2025 14:09
Base automatically changed from backup-improvements to main April 23, 2025 14:23
@vroldanbet vroldanbet force-pushed the improve-validation-errors branch from 879d932 to 8adc5ab Compare April 23, 2025 15:14
@vroldanbet vroldanbet enabled auto-merge April 23, 2025 15:14
Copy link
Contributor

@miparnisari miparnisari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you post examples of how the CLI looks before & after this PR? I understand:

Before this PR:

$ zed preview schema compile root.zed
Usage:
  zed preview schema compile <file> [flags]

Examples:

        Write to stdout:
                zed preview schema compile root.zed
        Write to an output file:
                zed preview schema compile --out compiled.zed
        

Flags:
  -h, --help         help for compile
      --out string   output filepath; omitting writes to stdout

Global Flags:
      --certificate-path string     path to certificate authority used to verify secure connections
      --endpoint string             spicedb gRPC API endpoint
      --hostname-override string    override the hostname used in the connection to the endpoint
      --insecure                    connect over a plaintext connection
      --log-format string           format of logs ("auto", "console", "json") (default "auto")
      --log-level string            verbosity of logging ("trace", "debug", "info", "warn", "error") (default "info")
      --max-message-size int        maximum size *in bytes* (defaults to 4_194_304 bytes ~= 4MB) of a gRPC message that can be sent or received by zed
      --no-verify-ca                do not attempt to verify the server's certificate chain and host name
      --permissions-system string   permissions system to query
      --request-id string           optional id to send along with SpiceDB requests for tracing
      --skip-version-check          if true, no version check is performed against the server
      --token string                token used to authenticate to SpiceDB

3:29PM ERR terminated with errors error="failed to read schema file: open root.zed: no such file or directory"

@vroldanbet vroldanbet force-pushed the improve-validation-errors branch 2 times, most recently from 883d20e to d1514db Compare April 24, 2025 12:28
@ecordell
Copy link
Contributor

I love the general idea of this, unfortunately I think this makes the UX a little worse in some other cases.

  1. It seems to have lost the logger formatting on the error
  2. It seems to be losing some context for the specific command usage and not displaying it, it now gives less info than before

Here's a common one I run into with zed (because I can never remember the check format - is it one string relation? 5 or 6 fields, one for each tuple component? nope - it's 3 for some reason).

Here's before this PR:

$ zed perm check
Usage:
  zed permission check <resource:id> <permission> <subject:id> [flags]

<rest of usage omitted for brevity>

10:52AM ERR terminated with errors error="accepts 3 arg(s), received 0"

and after:

$ zed perm check
accepts 3 arg(s), received 0
Usage:
  zed [command]

<rest of usage omitted for brevity>

Use "zed [command] --help" for more information about a command.

Note that prior to this PR it would give me the info I need - the format to put a check query.

@vroldanbet vroldanbet force-pushed the improve-validation-errors branch from d1514db to 11031ff Compare April 24, 2025 17:31
the usage was being printed on any error, which
was rather unpleasant to look at because it makes
the output difficult to parse for clues on what happened.
The whole goal of this commit is to improve UX.

Cobra supports "SilenceErrors" and "SilenceUsage", and a callback
function "SetFlagErrorFunc" for flag parsing errors. Unfortunately,
only a subset of errors fall under "flag parsing error" category.

To amend this, a special error Wrapper is introduced that signals
an error is a validation error, so the command can manually print
the usage when "SilenceUsage" is enabled, which this commit does.

A few tests are added that assert the output. Due to the
pervasive use of globals, some refactoring was conducted in
cmd.go to make it more test friendly.
@vroldanbet vroldanbet force-pushed the improve-validation-errors branch from 11031ff to b63f5e1 Compare April 24, 2025 17:32
Copy link
Contributor

@ecordell ecordell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@vroldanbet vroldanbet merged commit 0c95dac into main Apr 24, 2025
11 checks passed
@vroldanbet vroldanbet deleted the improve-validation-errors branch April 24, 2025 17:39
@github-actions github-actions bot locked and limited conversation to collaborators Apr 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants