Golang Rich Error, for having better visibility when things don't work as expected.

Overview

Rich Error

Why we need better error handling?

the error messages in go are ugly and very hard to read, also they don't give us much data about what exactly has happened. for having better observability on errors, we need some more data, this package helps to have those additional info to with less additional effort.

How does it work? what's the difference?

almost any error in go that happens in deeper layers, must be passed to its parent to finally generate the appropriate response to the client.

for example, we may have the error on the adapter layer here, but will not have a clue about how we have got there, what was the type of the error, and what was our runtime arguments that may have caused that error.

delivery
    |
    ├── interactor
        |
        ├── internal
            |
            ├── adapter <- this is where the error happens

to fix this, we will generate the RichError when the error occurs and then keep passing it to the higher level until we reach the top. and in each level we will add the related data to that layer.

the RichError features

in RichError, each error can have these:

  • op the name of the method or function
  • error the real error that has happened
  • message any additional message if you want to pass
  • meta_data any additional runtime argument that you may want to pass
  • kind which indicates the kind of the error, for example: forbidden, not found, or unexpected
  • code_info which will automatically add the exact file path and line that error has occurred

How to Install

$ go get github.com/p3ym4n/re 

How to Use

when ever the error happens you can use RichError like this:

on the deepest layer we will make the RichError

package user_repo

import "github.com/p3ym4n/re"

func (repo *UserRepo) FindUserById(userID uint) (*entity.User, re.Error) {
	const op = re.Op("user_repo.FindUserById") // <- this is the op that we make it as a const on top of each func 
	meta := re.Meta{"user_id": userID}         // <- this is the meta that hold the runtime arguments (optional)

	user, err := repo.handler.FindById(userID)
	if err != nil {
		return nil, re.New(op, err, meta, re.KindNotFound) // <- here we make the RichError
	}
	return user, nil
}

and on the higher levels we will just chain it to the next layer

package user_interactor

import "github.com/p3ym4n/re"

func (i *UserInteractor) GetListOfUsers() ([]*entity.User, re.Error) {
	const op = re.Op("user_interactor.GetListOfUsers") // <- we will make the op

	userIds := i.userRepo.GetAllAvaiables()
	users := make([]*entity.User, 0)
	for _, userID := range userIds {
		user, err := i.userRepo.FindUserById(userID)
		if err != nil {
			return nil, err.Chain(op) // <- here we just chain the RichError
		}
		users = append(users, user)
	}
	return users, nil
}

other examples for constructing:

const op = re.Op("package_name.func_name")

err := CallingAnything()
if err != nil{
    re.New(op, err) // <- in this case the kind will be Unexpected
}

err2 := CallingAnotherFunc()
if err2 != nil{
    re.New(op, err, KindForbidden, "you are not allowed to do this") // <- you can add additional data
}

other examples for chaining:

const op = re.Op("higher_package_name.func_name")

err := callingDeepChildWhoReturnsRichError()
return err.Chain(op)

err := callingAnotherDeepChildWhoReturnsRichError()
return err.ChainWithMeta(op, re.Meta{"arg1":"value1"})

for making a decision on how to show the error to the client you can have these attributes from the RichError:

package re

type Error interface {
	Kind() Kind // <- you can add kinds based on your business logics
	Message() string // <- if you have add any messages otherwise it will be ""
	Internal() error // <- this will return ths inner error

	RawMap() map[string]interface{} // <- it will return all the collected values in raw format
	ProcessedMap() map[string]string // <- same as RawMap() but with sanitized values

	Chain(op Op) Error
	ChainWithMeta(op Op, meta Meta) Error
}
Owner
Peyman Goldasteh
A Developer trying to dedicate his mess on the Backend.
Peyman Goldasteh
Errr - Errr (The Rich Structured Error Package missing from Go)

The errr package was created to fill the gap between error handling and error reporting.

Hamed Momeni 2 Feb 7, 2022
A feature-rich and easy to use logger for golang

A feature-rich and easy to use logger for golang ?? Install ?? Common Logs lumber.Success() lumber.Info() lumber.Debug() lumber.Warning()

Matthew Gleich 49 May 26, 2022
🪵 A dead simple, pretty, and feature-rich logger for golang

?? lumber ?? A dead simple, pretty, and feature-rich logger for golang ?? Install ?? Logging Functions lumber.Success() lumber.Info() lumber.Debug() l

Matt Gleich 49 May 26, 2022
Utilities for slightly better logging in Go (Golang).

logutils logutils is a Go package that augments the standard library "log" package to make logging a bit more modern, without fragmenting the Go ecosy

HashiCorp 324 Jun 14, 2022
Monitor pipe progress via output to standard error.

Pipe Monitor Monitor pipe progress via output to standard error. Similar to functionality provided by the Pipe Viewer (pv) command, except this comman

SoftCoil Development 5 May 2, 2022
Go-logger - A sample go module that I stood up quickly to learn how remote modules work in go

go-logger A sample go module that I stood up quickly to learn how remote modules

Stephen Ramirez 0 Jan 9, 2022
A helper tool to work with profile.proto (pprof) files

qpprof qpprof complements the pprof tool. Commands Use qpprof command --help to get more information. Flat aggregation Alternative flat aggregations a

Iskander (Alex) Sharipov 53 May 21, 2022
Simple and blazing fast lockfree logging library for golang

glg is simple golang logging library Requirement Go 1.11 Installation go get github.com/kpango/glg Example package main import ( "net/http" "time"

Yusuke Kato 158 Jun 22, 2022
Logging library for Golang

GLO Logging library for Golang Inspired by Monolog for PHP, severity levels are identical Install go get github.com/lajosbencz/glo Severity levels Deb

Lajos Bencz 14 Aug 26, 2021
a golang log lib supports level and multi handlers

go-log a golang log lib supports level and multi handlers Use import "github.com/siddontang/go-log/log" //log with different level log.Info("hello wo

siddontang 31 Jun 15, 2022
LogVoyage - logging SaaS written in GoLang

No longer maintained, sorry. Completely rewritten v2 is going to be released soon. Please follow http://github.com/logvoyage LogVoyage - fast and simp

null 91 Apr 21, 2022
An golang log lib, supports tracking and level, wrap by standard log lib

Logex An golang log lib, supports tracing and level, wrap by standard log lib How To Get shell go get gopkg.in/logex.v1 source code import "gopkg.in/

chzyer 39 Apr 15, 2022
Dead simple, super fast, zero allocation and modular logger for Golang

Onelog Onelog is a dead simple but very efficient JSON logger. It is one of the fastest JSON logger out there. Also, it is one of the logger with the

Francois Parquet 399 Jun 16, 2022
A Go (golang) package providing high-performance asynchronous logging, message filtering by severity and category, and multiple message targets.

ozzo-log Other languages 简体中文 Русский Description ozzo-log is a Go package providing enhanced logging support for Go programs. It has the following fe

Ozzo Framework 118 Jan 11, 2022
Golang logging library

Golang logging library Package logging implements a logging infrastructure for Go. Its output format is customizable and supports different logging ba

Örjan Fors 1.8k Jun 23, 2022
A system and resource monitoring tool written in Golang!

Grofer A clean and modern system and resource monitor written purely in golang using termui and gopsutil! Currently compatible with Linux only. Curren

PES Open Source Community 209 Jun 21, 2022
Golang beautify data display for Humans

Golang beautify data display for Humans English 简体中文 Usage Examples package main import ( ffmt "gopkg.in/ffmt.v1" ) func main() { example() } typ

ffmt 271 Jun 22, 2022
Logstash like, written in golang

gogstash Logstash like, written in golang Download gogstash from github check latest version Use docker image tsaikd/gogstash curl 'https://github.com

Tsai KD 592 Jun 22, 2022
Open Source Supreme Monitor Based on GoLang

Open Source Supreme Monitor Based on GoLang A module built for personal use but ended up being worthy to have it open sourced.

SneakyKiwi 19 May 6, 2022