v0.0.188 exerr MVP

This commit is contained in:
2023-07-24 10:42:39 +02:00
parent b1d6509294
commit 2e6ca48d22
14 changed files with 660 additions and 118 deletions

View File

@@ -2,10 +2,13 @@ package exerr
import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog"
"go.mongodb.org/mongo-driver/bson/primitive"
"gogs.mikescher.com/BlackForestBytes/goext/dataext"
"gogs.mikescher.com/BlackForestBytes/goext/langext"
"net/http"
"os"
@@ -17,21 +20,21 @@ import (
//
// ==== USAGE =====
//
// If some method returns an error _always wrap it into an bmerror:
// If some method returns an error _always wrap it into an exerror:
// value, err := do_something(..)
// if err != nil {
// return nil, bmerror.Wrap(err, "do something failed").Build()
// return nil, exerror.Wrap(err, "do something failed").Build()
// }
//
// If possible add metadata to the error (eg the id that was not found, ...), the methods are the same as in zerolog
// return nil, bmerror.Wrap(err, "do something failed").Str("someid", id).Int("count", in.Count).Build()
// return nil, exerror.Wrap(err, "do something failed").Str("someid", id).Int("count", in.Count).Build()
//
// You can change the errortype with `.User()` and `.System()` (User-errors are 400 and System-errors 500)
// You can also manually set the statuscode with `.WithStatuscode(http.NotFound)`
// You can set the type with `WithType(..)`
//
// New Errors (that don't wrap an existing err object) are created with New
// return nil, bmerror.New(bmerror.ErrInternal, "womethign wen horrible wrong").Build()
// return nil, exerror.New(exerror.TypeInternal, "womethign wen horrible wrong").Build()
// You can eitehr use an existing ErrorType, the "catch-all" ErrInternal, or add you own ErrType in consts.go
//
// All errors should be handled one of the following four ways:
@@ -64,37 +67,36 @@ func init() {
}
type Builder struct {
bmerror *bringmanError
errorData *ExErr
containsGinData bool
}
func Get(err error) *Builder {
return &Builder{bmerror: fromError(err)}
return &Builder{errorData: fromError(err)}
}
func New(t ErrorType, msg string) *Builder {
return &Builder{bmerror: newBringmanErr(CatSystem, t, msg)}
return &Builder{errorData: newExErr(CatSystem, t, msg)}
}
func Wrap(err error, msg string) *Builder {
return &Builder{bmerror: fromError(err).wrap(msg, CatWrap, 1)}
return &Builder{errorData: wrapExErr(fromError(err), msg, CatWrap, 1)}
}
// ----------------------------------------------------------------------------
func (b *Builder) WithType(t ErrorType) *Builder {
b.bmerror.Type = t
b.errorData.Type = t
return b
}
func (b *Builder) WithStatuscode(status int) *Builder {
b.bmerror.StatusCode = status
b.errorData.StatusCode = &status
return b
}
func (b *Builder) WithMessage(msg string) *Builder {
b.bmerror.Message = msg
b.errorData.Message = msg
return b
}
@@ -119,7 +121,7 @@ func (b *Builder) WithMessage(msg string) *Builder {
//
// - Send to the error-service
func (b *Builder) Err() *Builder {
b.bmerror.Severity = SevErr
b.errorData.Severity = SevErr
return b
}
@@ -138,7 +140,7 @@ func (b *Builder) Err() *Builder {
//
// - Logged as Warn
func (b *Builder) Warn() *Builder {
b.bmerror.Severity = SevWarn
b.errorData.Severity = SevWarn
return b
}
@@ -157,7 +159,7 @@ func (b *Builder) Warn() *Builder {
//
// - -(nothing)-
func (b *Builder) Info() *Builder {
b.bmerror.Severity = SevInfo
b.errorData.Severity = SevInfo
return b
}
@@ -167,12 +169,12 @@ func (b *Builder) Info() *Builder {
//
// Errors with category
func (b *Builder) User() *Builder {
b.bmerror.Category = CatUser
b.errorData.Category = CatUser
return b
}
func (b *Builder) System() *Builder {
b.bmerror.Category = CatSystem
b.errorData.Category = CatSystem
return b
}
@@ -268,7 +270,7 @@ func (b *Builder) Stack() *Builder {
func (b *Builder) Errs(key string, val []error) *Builder {
for i, valerr := range val {
b.addMeta(fmt.Sprintf("%v[%v]", key, i), MDTString, Get(valerr).toBMError().FormatLog(LogPrintFull))
b.addMeta(fmt.Sprintf("%v[%v]", key, i), MDTString, Get(valerr).errorData.FormatLog(LogPrintFull))
}
return b
}
@@ -299,7 +301,7 @@ func (b *Builder) GinReq(ctx context.Context, g *gin.Context, req *http.Request)
b.Str("gin.context.reqid", ctxVal)
}
if req.Method != "GET" && req.Body != nil && req.Header.Get("Content-Type") == "application/json" {
if brc, ok := req.Body.(langext.BufferedReadCloser); ok {
if brc, ok := req.Body.(dataext.BufferedReadCloser); ok {
if bin, err := brc.BufferedAll(); err == nil {
if len(bin) < 16*1024 {
var prettyJSON bytes.Buffer
@@ -348,13 +350,17 @@ func formatHeader(header map[string][]string) string {
// Build creates a new error, ready to pass up the stack
// If the errors is not SevWarn or SevInfo it gets also logged (in short form, without stacktrace) onto stdout
func (b *Builder) Build() error {
if b.bmerror.Severity == SevErr || b.bmerror.Severity == SevFatal {
b.bmerror.ShortLog(stackSkipLogger.Error())
warnOnPkgConfigNotInitialized()
if pkgconfig.ZeroLogErrTraces && (b.errorData.Severity == SevErr || b.errorData.Severity == SevFatal) {
b.errorData.ShortLog(stackSkipLogger.Error())
} else if pkgconfig.ZeroLogAllTraces {
b.errorData.ShortLog(stackSkipLogger.Error())
}
b.CallListener(MethodBuild)
return b.bmerror.ToGrpcError()
return b.errorData
}
// Output prints the error onto the gin stdout.
@@ -366,12 +372,12 @@ func (b *Builder) Output(ctx context.Context, g *gin.Context) {
b.GinReq(ctx, g, g.Request)
}
b.bmerror.Output(ctx, g)
b.errorData.Output(ctx, g)
if b.bmerror.Severity == SevErr || b.bmerror.Severity == SevFatal {
b.bmerror.Log(stackSkipLogger.Error())
} else if b.bmerror.Severity == SevWarn {
b.bmerror.Log(stackSkipLogger.Warn())
if b.errorData.Severity == SevErr || b.errorData.Severity == SevFatal {
b.errorData.Log(stackSkipLogger.Error())
} else if b.errorData.Severity == SevWarn {
b.errorData.Log(stackSkipLogger.Warn())
}
b.CallListener(MethodOutput)
@@ -380,24 +386,24 @@ func (b *Builder) Output(ctx context.Context, g *gin.Context) {
// Print prints the error
// If the error is SevErr we also send it to the error-service
func (b *Builder) Print() {
if b.bmerror.Severity == SevErr || b.bmerror.Severity == SevFatal {
b.bmerror.Log(stackSkipLogger.Error())
} else if b.bmerror.Severity == SevWarn {
b.bmerror.ShortLog(stackSkipLogger.Warn())
if b.errorData.Severity == SevErr || b.errorData.Severity == SevFatal {
b.errorData.Log(stackSkipLogger.Error())
} else if b.errorData.Severity == SevWarn {
b.errorData.ShortLog(stackSkipLogger.Warn())
}
b.CallListener(MethodPrint)
}
func (b *Builder) Format(level LogPrintLevel) string {
return b.bmerror.FormatLog(level)
return b.errorData.FormatLog(level)
}
// Fatal prints the error and terminates the program
// If the error is SevErr we also send it to the error-service
func (b *Builder) Fatal() {
b.bmerror.Severity = SevFatal
b.bmerror.Log(stackSkipLogger.WithLevel(zerolog.FatalLevel))
b.errorData.Severity = SevFatal
b.errorData.Log(stackSkipLogger.WithLevel(zerolog.FatalLevel))
b.CallListener(MethodFatal)
@@ -407,10 +413,6 @@ func (b *Builder) Fatal() {
// ----------------------------------------------------------------------------
func (b *Builder) addMeta(key string, mdtype metaDataType, val interface{}) *Builder {
b.bmerror.Meta.add(key, mdtype, val)
b.errorData.Meta.add(key, mdtype, val)
return b
}
func (b *Builder) toBMError() BMError {
return b.bmerror.ToBMError()
}