Files
trbot/utils/flaterr/wrapper.go

125 lines
3.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package flaterr
import (
"fmt"
"strings"
"github.com/rs/zerolog"
)
type Wrapper struct {
event *zerolog.Event
multErr *MultErr
isDiscard bool
err error
fields
}
type fields struct {
mBool map[string]bool
mInt map[string]int
mInt64 map[string]int64
mFloat64 map[string]float64
mStr map[string]string
mDict map[string]*zerolog.Event
mInts map[string][]int
}
// NewWrapper 传入一个 zerolog.Event 和 MultErr, 返回一个 Wrapper 等待后续链式调用
func NewWrapper(errEvent *zerolog.Event) *Wrapper {
return &Wrapper{
event: errEvent,
multErr: &MultErr{},
}
}
// Flat 返回 multErr 中的 Flat 方法
func (ew *Wrapper) Flat() error {
return ew.multErr.Flat()
}
// Err 记录错误等待后续链式调用
func (ew *Wrapper) Err(err error) *Wrapper {
newEvent := *ew.event
return &Wrapper{
event: newEvent.Err(err),
multErr: ew.multErr,
err: err,
}
}
// ErrIf 如果 err 为 nil则忽略后续的链式调用
func (ew *Wrapper) ErrIf(err error) *Wrapper {
if err == nil {
return &Wrapper{ isDiscard: true }
}
newEvent := *ew.event
return &Wrapper{
event: newEvent.Err(err),
multErr: ew.multErr,
err: err,
}
}
// Msg 为错误的描述,作为 err 的前缀
func (ew *Wrapper) Msg(msg string) {
if ew.isDiscard { return }
// ew.buildFields()
fieldStr := ew.buildFieldsString()
if msg != "" {
// 没有模板用 msg 和 error-wrapping
// ew.multErr.Addf("%s: %w", msg, ew.err)
ew.multErr.Addf("%s%s: %w", msg, fieldStr, ew.err)
// 按模板发日志
ew.event.Msg(msg)
} else {
// 什么都没有,直接塞到 multErr 里
ew.multErr.Add(ew.err)
// 直接发日志
ew.event.Send()
}
}
func (ew *Wrapper) MsgT(tmpl Msg, cont string) {
if ew.isDiscard { return }
ew.buildFields()
ew.event = ew.event.Str("content", cont)
// 有模板用模板
ew.multErr.Addt(tmpl, cont, ew.err)
// 按模板发日志
ew.event.Msg(tmpl.Str())
}
func (ew *Wrapper) buildFields() {
for k, v := range ew.mBool { ew.event.Bool(k, v) }
for k, v := range ew.mInt { ew.event.Int(k, v) }
for k, v := range ew.mInt64 { ew.event.Int64(k, v) }
for k, v := range ew.mFloat64 { ew.event.Float64(k, v) }
for k, v := range ew.mStr { ew.event.Str(k, v) }
for k, v := range ew.mDict { ew.event.Dict(k, v) }
for k, v := range ew.mInts { ew.event.Ints(k, v) }
}
func (ew *Wrapper) buildFieldsString() string {
var sb strings.Builder
sb.WriteString(` {"fields": {`)
for k, v := range ew.mBool { ew.event.Bool(k, v); sb.WriteString(fmt.Sprintf(`"%s": %v, `, k, v)) }
for k, v := range ew.mInt { ew.event.Int(k, v); sb.WriteString(fmt.Sprintf(`"%s": %v, `, k, v)) }
for k, v := range ew.mInt64 { ew.event.Int64(k, v); sb.WriteString(fmt.Sprintf(`"%s": %v, `, k, v)) }
for k, v := range ew.mFloat64 { ew.event.Float64(k, v); sb.WriteString(fmt.Sprintf(`"%s": %v, `, k, v)) }
for k, v := range ew.mStr { ew.event.Str(k, v); sb.WriteString(fmt.Sprintf(`"%s": "%v", `, k, v)) }
for k, v := range ew.mInts { ew.event.Ints(k, v) }
return strings.TrimRight(sb.String(), ", ") + "}}"
}