Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
7fe3e66cad
|
|||
a73d7d1654
|
|||
bbd7a7bc2c
|
|||
f5151eb214
|
|||
eefb9ac9f5
|
|||
468a7d212d
|
@@ -13,6 +13,7 @@ var (
|
|||||||
CatForeign = ErrorCategory{"Foreign"} // A foreign error that some component threw (e.g. an unknown mongodb error), happens if we call Wrap(..) on an non-bmerror value
|
CatForeign = ErrorCategory{"Foreign"} // A foreign error that some component threw (e.g. an unknown mongodb error), happens if we call Wrap(..) on an non-bmerror value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//goland:noinspection GoUnusedGlobalVariable
|
||||||
var AllCategories = []ErrorCategory{CatWrap, CatSystem, CatUser, CatForeign}
|
var AllCategories = []ErrorCategory{CatWrap, CatSystem, CatUser, CatForeign}
|
||||||
|
|
||||||
type ErrorSeverity struct{ Severity string }
|
type ErrorSeverity struct{ Severity string }
|
||||||
@@ -26,6 +27,7 @@ var (
|
|||||||
SevFatal = ErrorSeverity{"Fatal"}
|
SevFatal = ErrorSeverity{"Fatal"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//goland:noinspection GoUnusedGlobalVariable
|
||||||
var AllSeverities = []ErrorSeverity{SevTrace, SevDebug, SevInfo, SevWarn, SevErr, SevFatal}
|
var AllSeverities = []ErrorSeverity{SevTrace, SevDebug, SevInfo, SevWarn, SevErr, SevFatal}
|
||||||
|
|
||||||
type ErrorType struct {
|
type ErrorType struct {
|
||||||
@@ -33,6 +35,7 @@ type ErrorType struct {
|
|||||||
DefaultStatusCode *int
|
DefaultStatusCode *int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//goland:noinspection GoUnusedGlobalVariable
|
||||||
var (
|
var (
|
||||||
TypeInternal = ErrorType{"INTERNAL_ERROR", langext.Ptr(500)}
|
TypeInternal = ErrorType{"INTERNAL_ERROR", langext.Ptr(500)}
|
||||||
TypePanic = ErrorType{"PANIC", langext.Ptr(500)}
|
TypePanic = ErrorType{"PANIC", langext.Ptr(500)}
|
||||||
@@ -51,7 +54,7 @@ var (
|
|||||||
// other values come from pkgconfig
|
// other values come from pkgconfig
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewType(key string, defStatusCode *int) {
|
func NewType(key string, defStatusCode *int) ErrorType {
|
||||||
return ErrorType{key, defStatusCode}
|
return ErrorType{key, defStatusCode}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,8 +10,8 @@ type ErrorPackageConfig struct {
|
|||||||
ZeroLogAllTraces bool // autom print zerolog logs on .Build() (for all Severities)
|
ZeroLogAllTraces bool // autom print zerolog logs on .Build() (for all Severities)
|
||||||
RecursiveErrors bool // errors contains their Origin-Error
|
RecursiveErrors bool // errors contains their Origin-Error
|
||||||
ExtendedGinOutput bool // Log extended data (trace, meta, ...) to gin in err.Output()
|
ExtendedGinOutput bool // Log extended data (trace, meta, ...) to gin in err.Output()
|
||||||
ExtendGinOutput func(json map[string]any) // (Optionally) extend the gin output with more fields
|
ExtendGinOutput func(err *ExErr, json map[string]any) // (Optionally) extend the gin output with more fields
|
||||||
ExtendGinDataOutput func(json map[string]any) // (Optionally) extend the gin `__data` output with more fields
|
ExtendGinDataOutput func(err *ExErr, depth int, json map[string]any) // (Optionally) extend the gin `__data` output with more fields
|
||||||
}
|
}
|
||||||
|
|
||||||
type ErrorPackageConfigInit struct {
|
type ErrorPackageConfigInit struct {
|
||||||
@@ -19,8 +19,8 @@ type ErrorPackageConfigInit struct {
|
|||||||
ZeroLogAllTraces bool
|
ZeroLogAllTraces bool
|
||||||
RecursiveErrors bool
|
RecursiveErrors bool
|
||||||
ExtendedGinOutput bool
|
ExtendedGinOutput bool
|
||||||
ExtendGinOutput *func(json map[string]any)
|
ExtendGinOutput func(err *ExErr, json map[string]any)
|
||||||
ExtendGinDataOutput *func(json map[string]any)
|
ExtendGinDataOutput func(err *ExErr, depth int, json map[string]any)
|
||||||
}
|
}
|
||||||
|
|
||||||
var initialized = false
|
var initialized = false
|
||||||
@@ -30,8 +30,8 @@ var pkgconfig = ErrorPackageConfig{
|
|||||||
ZeroLogAllTraces: false,
|
ZeroLogAllTraces: false,
|
||||||
RecursiveErrors: true,
|
RecursiveErrors: true,
|
||||||
ExtendedGinOutput: false,
|
ExtendedGinOutput: false,
|
||||||
ExtendGinOutput: func(json map[string]any) {},
|
ExtendGinOutput: func(err *ExErr, json map[string]any) {},
|
||||||
ExtendGinDataOutput: func(json map[string]any) {},
|
ExtendGinDataOutput: func(err *ExErr, depth int, json map[string]any) {},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes the exerr packages
|
// Init initializes the exerr packages
|
||||||
@@ -42,13 +42,23 @@ func Init(cfg ErrorPackageConfigInit) {
|
|||||||
panic("Cannot re-init error package")
|
panic("Cannot re-init error package")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ego := func(err *ExErr, json map[string]any) {}
|
||||||
|
egdo := func(err *ExErr, depth int, json map[string]any) {}
|
||||||
|
|
||||||
|
if cfg.ExtendGinOutput != nil {
|
||||||
|
ego = cfg.ExtendGinOutput
|
||||||
|
}
|
||||||
|
if cfg.ExtendGinDataOutput != nil {
|
||||||
|
egdo = cfg.ExtendGinDataOutput
|
||||||
|
}
|
||||||
|
|
||||||
pkgconfig = ErrorPackageConfig{
|
pkgconfig = ErrorPackageConfig{
|
||||||
ZeroLogErrTraces: cfg.ZeroLogErrTraces,
|
ZeroLogErrTraces: cfg.ZeroLogErrTraces,
|
||||||
ZeroLogAllTraces: cfg.ZeroLogAllTraces,
|
ZeroLogAllTraces: cfg.ZeroLogAllTraces,
|
||||||
RecursiveErrors: cfg.RecursiveErrors,
|
RecursiveErrors: cfg.RecursiveErrors,
|
||||||
ExtendedGinOutput: cfg.ExtendedGinOutput,
|
ExtendedGinOutput: cfg.ExtendedGinOutput,
|
||||||
ExtendGinOutput: langext.Coalesce(cfg.ExtendGinOutput, func(json map[string]any) {}),
|
ExtendGinOutput: ego,
|
||||||
ExtendGinDataOutput: langext.Coalesce(cfg.ExtendGinDataOutput, func(json map[string]any) {}),
|
ExtendGinDataOutput: egdo,
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true
|
initialized = true
|
||||||
|
@@ -162,7 +162,6 @@ func (ee *ExErr) RecursiveStatuscode() *int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fallback to <empty>
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,6 +178,18 @@ func (ee *ExErr) RecursiveCategory() ErrorCategory {
|
|||||||
return ee.Category
|
return ee.Category
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RecursiveMeta searches (top-down) for teh first error that has a meta value with teh specified key
|
||||||
|
// and returns its value (or nil)
|
||||||
|
func (ee *ExErr) RecursiveMeta(key string) *MetaValue {
|
||||||
|
for curr := ee; curr != nil; curr = curr.OriginalError {
|
||||||
|
if metaval, ok := curr.Meta[key]; ok {
|
||||||
|
return langext.Ptr(metaval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ee *ExErr) Depth() int {
|
func (ee *ExErr) Depth() int {
|
||||||
if ee.OriginalError == nil {
|
if ee.OriginalError == nil {
|
||||||
return 1
|
return 1
|
||||||
|
32
exerr/gin.go
32
exerr/gin.go
@@ -7,43 +7,43 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ee *ExErr) toJson() gin.H {
|
func (ee *ExErr) toJson(depth int) gin.H {
|
||||||
json := gin.H{}
|
ginJson := gin.H{}
|
||||||
|
|
||||||
if ee.UniqueID != "" {
|
if ee.UniqueID != "" {
|
||||||
json["id"] = ee.UniqueID
|
ginJson["id"] = ee.UniqueID
|
||||||
}
|
}
|
||||||
if ee.Category != CatWrap {
|
if ee.Category != CatWrap {
|
||||||
json["category"] = ee.Category
|
ginJson["category"] = ee.Category
|
||||||
}
|
}
|
||||||
if ee.Type != TypeWrap {
|
if ee.Type != TypeWrap {
|
||||||
json["type"] = ee.Type
|
ginJson["type"] = ee.Type
|
||||||
}
|
}
|
||||||
if ee.StatusCode != nil {
|
if ee.StatusCode != nil {
|
||||||
json["statuscode"] = ee.StatusCode
|
ginJson["statuscode"] = ee.StatusCode
|
||||||
}
|
}
|
||||||
if ee.Message != "" {
|
if ee.Message != "" {
|
||||||
json["message"] = ee.Message
|
ginJson["message"] = ee.Message
|
||||||
}
|
}
|
||||||
if ee.Caller != "" {
|
if ee.Caller != "" {
|
||||||
json["caller"] = ee.Caller
|
ginJson["caller"] = ee.Caller
|
||||||
}
|
}
|
||||||
if ee.Severity != SevErr {
|
if ee.Severity != SevErr {
|
||||||
json["severity"] = ee.Severity
|
ginJson["severity"] = ee.Severity
|
||||||
}
|
}
|
||||||
if ee.Timestamp != (time.Time{}) {
|
if ee.Timestamp != (time.Time{}) {
|
||||||
json["time"] = ee.Timestamp.Format(time.RFC3339)
|
ginJson["time"] = ee.Timestamp.Format(time.RFC3339)
|
||||||
}
|
}
|
||||||
if ee.WrappedErrType != "" {
|
if ee.WrappedErrType != "" {
|
||||||
json["wrappedErrType"] = ee.WrappedErrType
|
ginJson["wrappedErrType"] = ee.WrappedErrType
|
||||||
}
|
}
|
||||||
if ee.OriginalError != nil {
|
if ee.OriginalError != nil {
|
||||||
json["original"] = ee.OriginalError.toJson()
|
ginJson["original"] = ee.OriginalError.toJson(depth + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgconfig.ExtendGinDataOutput(json)
|
pkgconfig.ExtendGinDataOutput(ee, depth, ginJson)
|
||||||
|
|
||||||
return json
|
return ginJson
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ee *ExErr) Output(g *gin.Context) {
|
func (ee *ExErr) Output(g *gin.Context) {
|
||||||
@@ -75,10 +75,10 @@ func (ee *ExErr) Output(g *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pkgconfig.ExtendedGinOutput {
|
if pkgconfig.ExtendedGinOutput {
|
||||||
ginOutput["__data"] = ee.toJson()
|
ginOutput["__data"] = ee.toJson(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgconfig.ExtendGinOutput(ginOutput)
|
pkgconfig.ExtendGinOutput(ee, ginOutput)
|
||||||
|
|
||||||
g.Render(statuscode, json.GoJsonRender{Data: ginOutput, NilSafeSlices: true, NilSafeMaps: true})
|
g.Render(statuscode, json.GoJsonRender{Data: ginOutput, NilSafeSlices: true, NilSafeMaps: true})
|
||||||
}
|
}
|
||||||
|
@@ -50,10 +50,3 @@ func (ac *AppContext) RequestURI() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *AppContext) FinishSuccess(res HTTPResponse) HTTPResponse {
|
|
||||||
if ac.cancelled {
|
|
||||||
panic("Cannot finish a cancelled request")
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
@@ -2,8 +2,10 @@ package ginext
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
)
|
)
|
||||||
@@ -40,33 +42,55 @@ func (pctx *PreContext) Form(form any) *PreContext {
|
|||||||
func (pctx PreContext) Start() (*AppContext, *gin.Context, *HTTPResponse) {
|
func (pctx PreContext) Start() (*AppContext, *gin.Context, *HTTPResponse) {
|
||||||
if pctx.uri != nil {
|
if pctx.uri != nil {
|
||||||
if err := pctx.ginCtx.ShouldBindUri(pctx.uri); err != nil {
|
if err := pctx.ginCtx.ShouldBindUri(pctx.uri); err != nil {
|
||||||
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, commonApiErr.BindFailURI, "Failed to read uri", err))
|
err = exerr.Wrap(err, "Failed to read uri").
|
||||||
|
WithType(exerr.TypeBindFailURI).
|
||||||
|
Str("struct_type", fmt.Sprintf("%T", pctx.uri)).
|
||||||
|
Build()
|
||||||
|
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pctx.query != nil {
|
if pctx.query != nil {
|
||||||
if err := pctx.ginCtx.ShouldBindQuery(pctx.query); err != nil {
|
if err := pctx.ginCtx.ShouldBindQuery(pctx.query); err != nil {
|
||||||
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, commonApiErr.BindFailQuery, "Failed to read query", err))
|
err = exerr.Wrap(err, "Failed to read query").
|
||||||
|
WithType(exerr.TypeBindFailQuery).
|
||||||
|
Str("struct_type", fmt.Sprintf("%T", pctx.query)).
|
||||||
|
Build()
|
||||||
|
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pctx.body != nil {
|
if pctx.body != nil {
|
||||||
if pctx.ginCtx.ContentType() == "application/json" {
|
if pctx.ginCtx.ContentType() == "application/json" {
|
||||||
if err := pctx.ginCtx.ShouldBindJSON(pctx.body); err != nil {
|
if err := pctx.ginCtx.ShouldBindJSON(pctx.body); err != nil {
|
||||||
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, commonApiErr.BindFailJSON, "Failed to read body", err))
|
err = exerr.Wrap(err, "Failed to read json-body").
|
||||||
|
WithType(exerr.TypeBindFailJSON).
|
||||||
|
Str("struct_type", fmt.Sprintf("%T", pctx.body)).
|
||||||
|
Build()
|
||||||
|
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, err))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, commonApiErr.BindFailJSON, "missing JSON body", nil))
|
err := exerr.New(exerr.TypeBindFailJSON, "missing JSON body").
|
||||||
|
Str("struct_type", fmt.Sprintf("%T", pctx.body)).
|
||||||
|
Build()
|
||||||
|
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pctx.form != nil {
|
if pctx.form != nil {
|
||||||
if pctx.ginCtx.ContentType() == "multipart/form-data" {
|
if pctx.ginCtx.ContentType() == "multipart/form-data" {
|
||||||
if err := pctx.ginCtx.ShouldBindWith(pctx.form, binding.Form); err != nil {
|
if err := pctx.ginCtx.ShouldBindWith(pctx.form, binding.Form); err != nil {
|
||||||
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, commonApiErr.BindFailFormData, "Failed to read multipart-form", err))
|
err = exerr.Wrap(err, "Failed to read multipart-form").
|
||||||
|
WithType(exerr.TypeBindFailFormData).
|
||||||
|
Str("struct_type", fmt.Sprintf("%T", pctx.form)).
|
||||||
|
Build()
|
||||||
|
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, err))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, commonApiErr.BindFailJSON, "missing form body", nil))
|
err := exerr.New(exerr.TypeBindFailFormData, "missing form body").
|
||||||
|
Str("struct_type", fmt.Sprintf("%T", pctx.form)).
|
||||||
|
Build()
|
||||||
|
return nil, nil, langext.Ptr(APIError(pctx.ginCtx, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
package goext
|
package goext
|
||||||
|
|
||||||
const GoextVersion = "0.0.190"
|
const GoextVersion = "0.0.196"
|
||||||
|
|
||||||
const GoextVersionTimestamp = "2023-07-24T11:16:57+0200"
|
const GoextVersionTimestamp = "2023-07-24T11:47:47+0200"
|
||||||
|
Reference in New Issue
Block a user