171 lines
2.7 KiB
Go
171 lines
2.7 KiB
Go
// 0.1.2
|
|
package errs
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
|
|
"git.leolab.info/lib/replacer"
|
|
)
|
|
|
|
type ErrCode string
|
|
|
|
var Silent = false
|
|
var StrFmt = "[ERROR] %date% %time% [%code%] %error% at %file%:%line% %func%"
|
|
var Trace = false
|
|
|
|
const (
|
|
ErrError ErrCode = "ErrError"
|
|
ErrNoError ErrCode = "ErrNoError"
|
|
ErrDSError ErrCode = "ErrDSError"
|
|
)
|
|
|
|
type src struct {
|
|
File string
|
|
Line int
|
|
Func string
|
|
}
|
|
|
|
//Структура ошибки
|
|
// 0.1.0
|
|
type Err struct {
|
|
dsId int64
|
|
Code ErrCode
|
|
Msg string
|
|
src src
|
|
Prev *Err
|
|
}
|
|
|
|
//Реализация интерфейса error
|
|
// 0.1.0
|
|
func (e *Err) Error() string {
|
|
if e == nil {
|
|
panic("NIL Error")
|
|
}
|
|
return e.Msg
|
|
}
|
|
|
|
//Получить "карту" ошибки
|
|
// 0.1.4
|
|
func (e *Err) Map() map[string]interface{} {
|
|
if e == nil {
|
|
panic("NIL Error")
|
|
}
|
|
ret := map[string]interface{}{
|
|
"DSId": e.dsId,
|
|
"Code": e.Code,
|
|
"Msg": e.Msg,
|
|
"Src": map[string]interface{}{
|
|
"File": e.src.File,
|
|
"Line": e.src.Line,
|
|
"Func": e.src.Func,
|
|
},
|
|
}
|
|
if e.Prev != nil {
|
|
ret["Prev"] = e.Error()
|
|
}
|
|
return ret
|
|
}
|
|
|
|
//Создать ошибку
|
|
// 0.1.4
|
|
func RaiseError(eCode ErrCode, msg string, prev ...*Err) *Err {
|
|
e := &Err{
|
|
Code: eCode,
|
|
Msg: msg,
|
|
src: getSrc(2),
|
|
Prev: nil,
|
|
}
|
|
if len(prev) > 0 {
|
|
e.Prev = prev[0]
|
|
}
|
|
e = storeDS(e)
|
|
logError(e)
|
|
return e
|
|
}
|
|
|
|
//Передать ошибку выше
|
|
// 0.1.4
|
|
func UpError(err *Err, args ...any) *Err {
|
|
e := &Err{
|
|
Code: err.Code,
|
|
Msg: err.Msg,
|
|
src: getSrc(2),
|
|
Prev: err,
|
|
}
|
|
if len(args) > 1 {
|
|
for _, a := range args {
|
|
switch v := a.(type) {
|
|
case string:
|
|
e.Msg = v
|
|
case ErrCode:
|
|
e.Code = v
|
|
default:
|
|
//Unknown
|
|
}
|
|
}
|
|
}
|
|
e = storeDS(e)
|
|
if Trace {
|
|
logError(e)
|
|
}
|
|
return e
|
|
}
|
|
|
|
//Преобразовать ошибку
|
|
// 0.1.0
|
|
func Error(e error) *Err {
|
|
err := &Err{
|
|
Code: ErrError,
|
|
Msg: e.Error(),
|
|
src: getSrc(2),
|
|
Prev: nil,
|
|
}
|
|
err = storeDS(err)
|
|
logError(err)
|
|
return err
|
|
}
|
|
|
|
//Получить источник
|
|
// 0.1.0
|
|
func getSrc(lvl int) (s src) {
|
|
pc, file, line, ok := runtime.Caller(lvl)
|
|
if !ok {
|
|
return src{File: "undefined", Line: 0, Func: "undefined()"}
|
|
}
|
|
f := runtime.CallersFrames([]uintptr{pc})
|
|
ff, _ := f.Next()
|
|
s = src{
|
|
File: file,
|
|
Line: line,
|
|
Func: ff.Function,
|
|
}
|
|
return s
|
|
}
|
|
|
|
//Получить строку по формату
|
|
// 0.1.0
|
|
func (e *Err) getString() string {
|
|
if e == nil {
|
|
panic("Err is NIL")
|
|
}
|
|
r := replacer.New()
|
|
r.Add("code", string(e.Code))
|
|
r.Add("file", e.src.File)
|
|
r.Add("line", fmt.Sprintf("%v", e.src.Line))
|
|
r.Add("func", e.src.Func)
|
|
r.Add("error", e.Msg)
|
|
return r.ReplaceC(StrFmt)
|
|
}
|
|
|
|
//Вывести ошибку
|
|
// 0.1.0
|
|
func logError(e *Err) {
|
|
storeFS(e)
|
|
if Silent {
|
|
return
|
|
}
|
|
fmt.Fprintln(os.Stderr, e.getString())
|
|
}
|