fyictl

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2023 License: MIT

README ΒΆ

GitHub release Nix Devshell Continuous Integration License Language Go Report Card

Logo

fyictl

Explore the docs Β»

error.fyi fyictl is a utility CLI to aid developers with the generation and maintenance of user facing errors in software applications.

Features Β· Installation Β· Get Started Β· Usage Β· Report Bug


Warning The project is not production ready and very experimental.

Motivation

When developing a software application error messages tend to be an afterthought or forgotten all together, which in turn might make for a poor user experience when troubleshooting errors. With error.fyi I hope to improve the story around error messaging and troubleshooting.

An error wrapped using error.fyi's client libraries, should always be able to answer the following:

  • What caused the issue?
  • How they could solve the issue.
  • What to do to solve the issue.

πŸ“š Features

  • Provides application users with better context for troubleshooting errors.
  • Easy integration with existing Go applications.
  • Provides in-code documentation generation.
  • Simple markdown documentation generation.
    • Supports custom markdown templates.

(back to top)

πŸš€ Get Started

Get started by installing error.fyi CLI, fyictl.

curl -sfL https://raw.githubusercontent.com/error-fyi/fyictl/main/install.sh | sh -

and importing the Go client library.

go get -u github.com/error-fyi/go-fyi@latest
Add additional error context

Once the previous prerequisites are met you should be ready to use fyictl to add more context to the errors in your Go projects.

We'll use this simple program, with only the main.go, to demonstrate the tool's utility.

   package main

import (
  "errors"
  "log"
)

func main() {
  err := doSomething()
  if err != nil {
    log.Fatal(err)
  }
}

func doSomething() error {
  // TODO improve this error message
  err := errors.New("something went wrong, please try again")
  return err
}

The program will print an error to the user telling them something went wrong. Although polite the error message isn't answering the question a user might have when encountering an error:

  • What caused the issue?
  • How they could solve the issue.
  • What to do to solve the issue.

Now let's use fyictl to improve thing.

From your terminal window in the Go project directory run the following:

fyictl init --wrap

Tip

To configure fyictl to target errors with a TODO prefix you can add the --todo flag, like in the example:

fyictl init --wrap --todo

Now the program should look something like this:

package main

import (
	"errors"
	"log"

	fyi "github.com/error-fyi/go-fyi"
)

// @fyi name <CHANGE ME>
// @fyi title <CHANGE ME>
// @fyi base_url <CHANGE ME>
// @fyi version v0.1.0
// @fyi description <CHANGE ME>
func main() {
	err := doSomething()
	if err != nil {
		log.Fatal(err)
	}
}

func doSomething() error {
	// TODO improve this error message
	err := errors.New("something went wrong, please try again")
	// @fyi.error code main_error_18
	// @fyi.error title <CHANGE ME TO A NICE TITLE>
	// @fyi.error short <TL;DR ON THE CAUSE OF THE ERROR>
	// @fyi.error severity severe|medium|low
	// @fyi.error.suggestion short <TL;DR ON HOW CAN THE ERROR BE FIXED?>
	return fyi.Error(err, "main_error_18")
}

The tools ha done a few things:

  • Has added annotations above the main() with fields to describe the application.
  • Has added annotations around the error, that add additional context to the error.
  • Has wrapped the returning error with the error.fyi error wrapper.

All the annotation values can be updated, even the error code, but for this example we'll limit to updating the required fields. More information about the annotations is available here.

Init command can be used for already existing projects, and it will recursively explore the packages for errors.

Tip

fyictl also provides an annotate command which annotate a single file

fyictl annotate -f main.go
package main

import (
	"errors"
	"log"

	fyi "github.com/error-fyi/go-fyi"
)

// @fyi name example-app
// @fyi title Example App
// @fyi base_url docs.example.com
// @fyi version v0.1.0
func main() {
	err := doSomething()
	if err != nil {
		log.Fatal(err)
	}
}

func doSomething() error {
	// TODO improve this error message
	err := errors.New("something went wrong, please try again")
	// @fyi.error code main_error_18
	// @fyi.error title Transaction Error
	// @fyi.error short There was an error during transaction, value exceeded limit
	// @fyi.error severity low
	// @fyi.error.suggestion short Retry the transaction with a lower input value
	return fyi.Error(err, "main_error_18")
}

Now we can generate the application error manifest, this a yaml manifest containing information about the different errors in an application.

From the terminal run:

fyictl manifest -o errors.yaml 

The following our simple program application error manifest.

Example error manifest.
---
# Code generated by fyictl: https://github.com/tfadeyi/errors.
# DO NOT EDIT.
base_url: docs.example.com
errors_definitions:
    main_error_18:
        code: main_error_18
        meta:
            loc:
                filename: main.go
                line: 24
        severity: low
        short: There was an error during transaction, value exceeded limit
        suggestions:
            "1":
                error_code: main_error_18
                id: "1"
                short: Retry the transaction with a lower input value
        title: Transaction Error
name: example-app
title: Example App
version: v0.1.0

Once we have the manifest we can embed it into our application and make it available at runtime.

package main

import (
	"errors"
	"log"
	_"embed"

	fyi "github.com/error-fyi/go-fyi"
)

//go:embed errors.yaml
var errorsYAML []byte

// @fyi name example-app
// @fyi title Example App
// @fyi base_url docs.example.com
// @fyi version v0.1.0
func main() {
	fyi.Manifest(errorsYAML)
	err := doSomething()
	if err != nil {
		log.Fatal(err)
	}
}

func doSomething() error {
	// TODO improve this error message
	err := errors.New("something went wrong, please try again")
	// @fyi.error code main_error_18
	// @fyi.error title Transaction Error
	// @fyi.error short There was an error during transaction, value exceeded limit
	// @fyi.error severity low
	// @fyi.error.suggestion short Retry the transaction with a lower input value
	return fyi.Error(err, "main_error_18")
}

Let's now run our simple application:

Example error output.
$ go run main.go
2023/10/03 22:46:12 [something went wrong, please try again]

   TRANSACTION ERROR                                                          
                                                                              
  ## What caused the error                                                    
                                                                              
  There was an error during transaction, value exceeded limit                 
                                                                              
  ## Quick Solutions                                                          
                                                                              
  β”‚ Additional information is available at: docs.example.com/example-          
  β”‚ app/errors/main_error_18                                                   
                                                                              
  β€’ Suggestion: Retry the transaction with a lower input value                

exit status 1
Generate Markdown Documentation

fyictl also allows you to further generate markdown documentation based on the error manifest.

fyictl docs generate -f errors.yaml 

This will generate the markdown documentation under the default directory ./docs.

Tip

You can change the output directory by specifying the flag --output followed by the directory you want to target.

.
β”œβ”€β”€ docs
β”‚Β Β  β”œβ”€β”€ main_error_18.md
└── index.md
1 directory, 2 files

Example of `index.md` contents.
---
title: example-app
---

## example-app

**Application**: example-app
**Version**: v0.1.0

### Error definitions


* [**main_error_18**](./errors/main_error_18): There was an error during transaction, value exceeded limit

Example of `error definition`.
---
title: Transaction Error
code: main_error_18
---

## Transaction Error

**Code**: main_error_18

### Summary

There was an error during transaction, value exceeded limit

Expose Documentation

Once the documentation is generated you can use tools like GitHub Pages to host and expose it to your application's users.

GitHub Pages

Check GitHub's docs for how to setup a static page.

Make sure to set the Custom Domain value to match what was defined in @fyi base_url docs.example.com.

(back to top)

License

error.fyi is released under the MIT License.

(back to top)

Directories ΒΆ

Path Synopsis
cmd
app
app/options
Package options handles the different options the binary commands has.
Package options handles the different options the binary commands has.
app/options/manifest
Package spec contains the different options present under the spec generation command.
Package spec contains the different options present under the spec generation command.
internal
logging
Package logging uses the logr.Logger interface to integrate with different logging implementation for structured logging
Package logging uses the logr.Logger interface to integrate with different logging implementation for structured logging
version
Package version, returns the build info of the binary
Package version, returns the build info of the binary
tools

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL