github.com/confluentinc/cli@v1.100.0/errors.md (about)

     1  # Errors And Messages Handling
     2  
     3  The CLI codebase stores the strings of all messages in one location: the errors package [internal/pkg/errors](internal/pkg/errors). This encompasses all kinds of communication with the users, whether it be error messages, or message indicating success (e.g. successfully deleting a Kafka cluster). The goal is to ease the verification of consistency and correctness of messages, and to simplify future work in internationalizing the CLI.
     4  
     5  ## General Message Format
     6  - `""` surrounding names and ID’s
     7      - e.g. `Check that the resource "lkc-abc" exists.`, `Error: topic "bob" does not exist`
     8  - ```` `` ```` surrounding commands or flags
     9      - e.g. ``You must pass `--cluster` flag with the command or set an active Kafka in your context with `ccloud kafka cluster use`.``
    10  
    11  ## Creating an Error
    12  ### Message Format
    13  Error message format
    14  - short one line description describing what the error is
    15  - do not capitalize the first letter (unless the first word is a name)
    16  - do not add full stop at the end
    17  - the variable name must end with *ErrorMsg*
    18  
    19  Any suggestions of the type of actions the users should take, or any longer description should be kept in the suggestions section.
    20  Suggestion message is not required.
    21  Suggestions format
    22  - full sentence
    23  - capitalize first letter
    24  - end with a full stop 
    25  - the variable name must end with *Suggestions*
    26  
    27  examples:
    28  ```
    29  > ./ccloud ksql app create kk --cluster lkc-asfdsaf
    30  Error: Kafka cluster "lkc-asfdsaf" not found
    31  
    32  Suggestions:
    33      List Kafka clusters with `ccloud kafka cluster list`.
    34  ```
    35  ```
    36  Error: no API key selected for resource "lkc-dvnr7"
    37  
    38  Suggestions:
    39      Select an API key for resource "lkc-dvnr7" with `ccloud api-key use <API_KEY> --resource lkc-dvnr7`.
    40      To do so, you must have either already created or stored an API key for the resource.
    41      To create an API key use `ccloud api-key create --resource lkc-dvnr7`.
    42      To store an existing API key use `ccloud api-key store --resource lkc-dvnr7`.
    43  ```
    44  ```
    45  Error: Kafka cluster "lkc-yydnp" not ready
    46  
    47  Suggestions:
    48      It may take up to 5 minutes for a recently created Kafka cluster to be ready.
    49  ```
    50  
    51  ## Initializing the errors
    52  There are four ways to create errors for the CLI.
    53  
    54  1. All basic errors will fall under this category. Use one of the error intializing functions in the errors package (errors.New, errors.Errorf, errors.Wrap, errors.Wrapf), with an error message defined in [error_message.go](internal/pkg/errors/error_message.go). The name of the variable must end with *ErrorMsg*.
    55  ```
    56  errors.Errorf(errors.AuthorizeAccountsErrorMsg, accountsStr)
    57  ```
    58  2. For errors with suggestions, define the error message, and suggestions message next to each other in [error_message.go](internal/pkg/errors/error_message.go). The messages must have the same name with different ending following the naming convention (i.e. *ErrorMsg* and *Suggestions*). Then either `errors.NewErrorWithSuggestion` or `errors.NewWrapErrorWithSuggestion` is used to initialize the error.
    59  
    60  ```
    61  ResolvingConfigPathErrorMsg        = "error resolving the config filepath at \"%s\" has occurred"
    62  ResolvingConfigPathSuggestions     = "Try moving the config file to a different location."
    63  
    64  return "", errors.NewErrorWithSuggestions(fmt.Sprintf(errors.ResolvingConfigPathErrorMsg, c.Filename), errors.ResolvingConfigPathSuggestions)
    65  ```
    66  
    67  ```
    68  LookUpRoleErrorMsg              = "failed to lookup role \"%s\""
    69  LookUpRoleSuggestions           = "To check for valid roles, use `confluent role list`."
    70  
    71  return errors.NewWrapErrorWithSuggestions(err, fmt.Sprintf(errors.LookUpRoleErrorMsg, roleName), errors.LookUpRoleSuggestions)
    72  ```
    73  
    74  3. If you know that your error will be used in many places, or need to be caught donwstream and process later, you can define typed error by implenting the `CLITypedError` interface
    75  ```
    76  type CLITypedError interface {
    77  	error
    78  	UserFacingError() error
    79  }
    80  ```
    81    See [typed.go](internal/pkg/errors/typed.go) for examples and interface definition.
    82  
    83  4. For important errors that are thrown by external packages that need to be caught and translated, define a catcher in [catcher.go](internal/pkg/errors/catcher.go). The catcher can then be either inserted anyhwere in the CLI repo, or simply in `handleErrors` function in [handle.go](internal/pkg/errors/handle.go).
    84  
    85  ## HandleCommon
    86  `errors.HandleCommon` is called for every cobra RunE or PrerunE command, to handle common logic required for all errors, including turning off the usage message. This is done under the hood when defining new CLI RunE and PrerunE with `cmd.NewCLIRunE` and `cmd.NewCLIPrerunE` intializers.
    87  
    88  ## Non-error communcation
    89  For all non-error messages, define the string variables in [strings.go](internal/pkg/errors/strings.go), with variables name ending with *Msg*. The only exception being that warning messages are defined in [warning_message.go](internal/pkg/errors/warning_message.go) instead.