Skip to content
/ trier Public

a heavily Zig-inspired approach to error handling in Go

License

Notifications You must be signed in to change notification settings

syke99/trier

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

trier

Go Reference go reportcard License Go version
a heavily Zig-inspired approach to error handling in Go

Why use trier?

One of Go's biggest complaints is verbose error handling. You might have a function with 10 or more if err != nil checks, causing functions to bloat. With trier, you can create a trier and then chain function calls and return the first error encountered without having to clutter your code with if err != nil checks everywhere. It's heavily inspired by Zig's try keyword that doesn't use catch blocks. Instead, it internally stores and checks errors before trying the next chained function. You can chain as many functions together as you want, and then do your own final check on nil errors by calling tr.Err() (example below)

How do I use trier?

Installation

go get github.com/syke99/trier

Basic Usage

package main

import (
    "errors"

    "github.com/syke99/trier"
)

// create the functions you want to be
// tried (they can also just be passed 
// as anonymous functions)
func passOrFail(args ...any) error {
    if len(args) != 0 {
        return errors.New("failed passOrFail")
    }
    return nil
}

func failIfString(args ...any) error {
    var err error
    
    switch args[0].(type) {
    case string:
        err = errors.New("failedIfString")
    }
    return err
}

func main() {
    // create a new trier by calling trier.NewTrier()
    tr := trier.NewTrier()
    
    // try your functions by 
    // chaining them in tr.Try() calls
    // and passing the appropriate args
    // (in this example, even though the
    // second time trying failIfString 
    // should return an error, the trier's
    // error will be "failed passOrFail"
    // because the second time trying
    // passOrFail returned an error before
    // the second time trying failIfString)
    tr.Try(passOrFail).
        Try(failIfString, 0).
        Try(passOrFail, true).
        Try(failIfString, "hi")
    
    // prints "failed passOrFail
    println(tr.Err().Error())
}

More Advanced Usage

package main

import (
	"database/sql"
        "errors"
	"fmt"


	"github.com/syke99/trier"
	_ "github.com/go-sql-driver/mysql"
)

func dsn(dbName string) string {
	return fmt.Sprintf("%s:%s@tcp(%s)/%s", username, password, hostname, dbName)
}

func main() {
        // create a new trier by calling trier.NewTrier()
        tr := trier.NewTrier()

	var err error
	
	var db *sql.DB
	
	var tx *sql.Tx
	
	tr.Try(func(args ...any) error {
		db, err = sql.Open("mysql", dsn(""))
		return err
	}).Try(func(args ...any) error {
                tx, err = db.Begin()
		return err
	}).Try(func(args ...any) error {
                _, err = tx.Exec("UPDATE customers SET name = \"Jane Doe\" WHERE ID = 1")
		return err
	})
	
	if err != nil {
		if tx != nil {
			tx.Rollback()
                }
		panic(err)
        }
	
	tx.Commit()
}

More examples (such as anonymous functions, *.TryJoin(), etc) can be found here

Who?

This library was developed by Quinn Millican (@syke99)

License

This repo is under the MIT license, see LICENSE for details.

About

a heavily Zig-inspired approach to error handling in Go

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages