Categorygithub.com/sprak3000/go-glitch
module
1.1.0
Repository: https://github.com/sprak3000/go-glitch.git
Documentation: pkg.go.dev

# README

go-glitch

Code Quality & Tests Maintainability Test Coverage

This package is designed to help with handling errors from databases and web services. The glitch.DataError structure allows the logic layer of your code to use its error code to handle each machine-readable code in a user-friendly way.

Interested in making this library better? Read through our development guide.

Using DataError

Create a new glitch.DataError.

// Original error
innerErr := errors.New('root error cause')
// The error code and user-friendly error message you wish to expose
errCode := 'ErrorAPICrash'
msg := 'API experienced an error'

err := glitch.NewDataError(innerErr, errCode, msg)

DataError satisfies the error interface.

fmt.Println(err.Error())

// Prints:
//  Code: [ErrorAPICrash] Message: [API experienced an error] Inner error: [root error cause]"

Access the individual error details through err.Code(), err.Inner().

You can also wrap a DataError within a DataError.

err := glitch.NewDataError(nil, "ErrorDatabaseUnavailable", "no database connection available")
newErr := glitch.NewDataError(nil, "ErrorServiceUnavailable", "service down")
newErr.Wrap(err)

// Get the wrapped error
origErr := newErr.GetCause()

Handling database errors

PostgreSQL (lib/pq) errors

You can convert a lib/pq error into a glitch.DataError using postgres.ToDataError().

query := "CALL do_work($1)"
_, err := d.conn.ExecContext(ctx, query, workID)
return postgres.ToDataError(err, fmt.Sprintf("error doing work ID %s", workID))

API errors

Handling a "Problem Details for HTTP APIs" (RFC 7807) response from an API

If a web service implements the "Problem Details for HTTP APIs" specification, you can unmarshal the API responses into the glitch.HTTPProblem structure and then convert that into a glitch.DataError to return to the client logic using glitch.FromHTTPProblem.

var status int
var ret []btye
status, ret := callAPI()

if status >= 400 || status < 200 {
	prob := glitch.HTTPProblem{}
	err := json.Unmarshl(ret, &prob)
	if err != nil {
        return glitch.NewDataError(err, "ErrorJSONUnmarshal", "Could not decode error response")
    }

	return glitch.FromHTTPProblem(prob, "Error calling the API")
}

Creating a "Problem Details for HTTP APIs" (RFC 7807) response

Your own service can return an RFC 7807 problem response. This package defines an additional and optional Code field to return an API specific error code.

// GetUser() will return a user structure on success or a glitch.DataError on failure.
user, err := db.GetUser(id)

if err != nil {
	var status int
	var err string
	var title string
	var code string

	switch err.Code() {
	case userNotFound:
		status = http.StatusNotFound
		err = "User could not be found"
		title = "Not Found"
		code = "ErrorNotFound"
	case dbConnection:
		status = http.StatusServiceUnavailable
		err = "Database error. Contact customer support."
		title = "Database Error"
		code = "ErrorDatabase"
	default:
		status = http.StatusInternalServerError
		err = "Service error. Contact customer support."
		title = "Internal Error"
		code = "ErrorInternal"
    }

	httpProblem := glitch.HTTPProblem{
        Status:   status,
		Detail:   err,
		Type:     "https://example.net/validation-error",
        Title:    title,
        Instance: "/foo/bar",
        Code:     code,
    }

    ret, _ := json.Marshal(httpErr)
    w.WriteHeader(status)
    w.Write(ret)
    return
}

# Packages

Package glitch provides the DataError type and utilities to convert RFC 7807 errors into a DataError.
Package postgres provides a way to convert a lib/pq error to a glitch.DataError.