gocommon/aerr/aerr.go
Matthieu 'JP' DERASSE 77b4351ef1
All checks were successful
continuous-integration/drone/push Build is passing
feat(error): Create api error. WIP
2023-08-22 19:59:44 +00:00

110 lines
2.3 KiB
Go

package aerr
import (
"encoding/json"
"errors"
"fmt"
)
// Error represent a API Error. It will mainly be used in the Handler.
type Error struct {
// shown in Json
Code int `json:"code"`
DebugId string `json:"debug_id"`
Msg string `json:"message"`
// not in Json
httpCode int `json:"-"`
origin error `json:"-"`
}
// Error implements error interface.
func (e *Error) Error() string {
s := fmt.Sprintf("Error: %d.", e.Code)
// if we have a message, add it
if e.Msg != "" {
s = fmt.Sprintf("%s Message: %s.", s, e.Msg)
}
// if we have an origin message, add it.
if e.origin != nil {
s = fmt.Sprintf("%s Origin Message: %s.", s, e.origin.Error())
}
// add debugId
if e.DebugId != "" {
s = fmt.Sprintf("%s - %s", s, e.DebugId)
}
return s
}
// MarshalJSON will JSON marshal an Error. It will try to get message from the origin if there is none in the current Error.
func (e *Error) MarshalJSON() ([]byte, error) {
type TmpJson Error
// let's get the origin message if the current message is empty
if e.Msg == "" && e.origin != nil {
var originE *Error
if errors.As(e.origin, &originE) {
e.Msg = originE.Message()
} else {
e.Msg = e.origin.Error()
}
}
return json.Marshal((*TmpJson)(e))
}
// Add a bunch of setter / Getter
// SetDebugID allow to overide/set a debug Id and return the error.
func (e *Error) SetDebugID(d string) *Error {
e.DebugId = d
return e
}
// SetOrigin allow to set an origin error to the error and return that error.
func (e *Error) SetOrigin(origin error) *Error {
e.origin = origin
return e
}
// SetMessage allow to set a message to the error and return that error.
func (e *Error) SetMessage(msg string) *Error {
e.Msg = msg
return e
}
// SetCode allow to set a specific code to the error and return that error.
func (e *Error) SetCode(code int) *Error {
e.httpCode = code
return e
}
// Message will get the current error Msg. If none, it will try to go to origins until finding a message.
func (e *Error) Message() string {
if e.Msg == "" && e.origin != nil {
var originE *Error
if errors.As(e.origin, &originE) {
return originE.Message()
}
return e.origin.Error()
}
return e.Msg
}
// HttpCode will return the http code of the error.
func (e *Error) HttpCode() int {
return e.httpCode
}
// Unwrap will return the origin error.
func (e *Error) Unwrap() error {
return e.origin
}