seguims con los errores

master
DEV 3 years ago
parent 4338ed6787
commit 11b8bf37cd

@ -31,13 +31,13 @@ type (
Formatter interface {
Format (err error) []byte
FormatError(err error) []byte
}
FormatterFnc func(err error) []byte
)
func (f FormatterFnc) Format (err error) []byte {
func (f FormatterFnc) FormatError(err error) []byte {
return f(err) }

@ -85,7 +85,7 @@ func NewErrTextFormatter(options ...FmtTextFnc) *ErrTextFormatter {
}
func (f *ErrTextFormatter) Format (err error) []byte {
func (f *ErrTextFormatter) FormatError(err error) []byte {
if err == nil {
return nil
}

@ -72,4 +72,4 @@ func (e ErrCause) ToErrTrace(offset int) ErrTrace {
func (e ErrCause) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }

@ -61,4 +61,4 @@ func (e ErrCode) ToErrTrace(offset int) ErrTrace {
func (e ErrCode) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }

@ -86,4 +86,4 @@ func (l ErrGroup) ToErrTrace(offset int) ErrTrace {
func (l ErrGroup) String () string {
return string(G.Formatter.Format(l)) }
return string(G.Formatter.FormatError(l)) }

@ -90,6 +90,6 @@ func (e ErrInfo) StackTrace () StackTrace {
func (e ErrInfo) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }

@ -73,4 +73,4 @@ func (e ErrMulti) ToErrTrace(offset int) ErrTrace {
func (e ErrMulti) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }

@ -59,4 +59,4 @@ func (e ErrPanic) ToInfo (options ...ErrInfoFnc) ErrInfo {
func (e ErrPanic) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }

@ -65,4 +65,4 @@ func (e ErrTrace) ToErrMetas (options ...ErrInfoFnc) *ErrInfo {
func (e ErrTrace) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }

@ -28,7 +28,7 @@ type (
ErrorFormatter interface {
Format (err error) []byte
FormatError(err error) []byte
}
FormatErrorFnc func (err error)

@ -80,7 +80,7 @@ func NewFmtText(options ...FmtTextFnc) *FmtText {
func (f *FmtText) Format (err error) (res []byte) {
func (f *FmtText) FormatError(err error) (res []byte) {
if err == nil {
return nil
}

@ -27,7 +27,7 @@ type (
Formatter interface {
Format (err error) []byte
FormatError(err error) []byte
}
FormatFnc func (err error) []byte
@ -35,7 +35,7 @@ type (
)
func (f FormatFnc) Format (err error) []byte {
func (f FormatFnc) FormatError(err error) []byte {
return f(err) }

@ -60,7 +60,7 @@ type (
func (f *TextFmt) Format (err error) []byte {
func (f *TextFmt) FormatError(err error) []byte {
st := efmt.state{
}

@ -77,22 +77,22 @@ func (s *state) AddHead(code, errType string) {
func (s *state) AddFieldInt (name string, value int ) {
func (s *state) BuildInt(name string, value int ) {
s.addField(name,fmt.Sprintf(s.f.intLayout,value)) }
func (s *state) AddFieldBool (name string, value bool ) {
func (s *state) BuildBool(name string, value bool ) {
s.addField(name,fmt.Sprintf(s.f.boolLayout,value)) }
func (s *state) AddFieldFloat (name string, value float64 ) {
func (s *state) BuildFloat(name string, value float64 ) {
s.addField(name,fmt.Sprintf(s.f.floatLayout,value)) }
func (s *state) AddFieldTime (name string, value time.Time) {
func (s *state) BuildTime(name string, value time.Time) {
s.addField(name,fmt.Sprintf(s.f.timeLayout, value)) }
func (s *state) AddFieldDate (name string, value time.Time) {
func (s *state) BuildDate(name string, value time.Time) {
s.addField(name,fmt.Sprintf(s.f.dateLayout,value)) }
func (s *state) AddFieldString (name, value string) {
func (s *state) BuildString(name, value string) {
s.addField(name,value) }

@ -50,6 +50,10 @@ func fm (b *bytes.Buffer, e error, l int) {
}
*/
func (c MiCustomErr) Error () string {
return "ERRRROPROO"
}
func (c MiCustomErr) Unwrap () error {
return c.error
}
@ -70,21 +74,28 @@ func main() {
ne := i.WrapWithCause(errors.New("UnNuevoErrrorrrr"))
//e1 := errors.New("UnError")
//e2 := errs.WrapWithInfo(errors.New("ElOtro error"),errs.ErrInfoWithMessage("OtroError"))
//e3 := errs.NewErrMulti(e1,e2)
e1 := errors.New("UnError")
e2 := errs.WrapWithInfo(errors.New("ElOtro error"),errs.ErrInfoWithMessage("OtroError"))
e3 := errs.NewErrMulti(e1,e2)
fmt.Print(errs.ToFormat(ne,nil))
/*
e4 := &MiCustomErr{}
e5 := &MiCustomErr{}
me := errs.NewErrMulti(e3,e4,e5,ne).WrapWithInfo(errs.ErrInfoWithMessage("Es0"))
fmt.Print(errs.ToFormat(me,nil))
/*
fmt.Print(errs.ToFormat(e4,nil))
fmt.Print(errs.ToFormat(e5,nil))
*/
*/
}

@ -26,7 +26,8 @@ package errs
import (
"errs/efmt"
"errs/efmt/err_text_fmt"
"errs/fmtr"
"errs/fmtr/ftext"
"errs/stack"
"fmt"
"reflect"
@ -36,7 +37,7 @@ import (
const (
CodePanicError string = "panic"
CodeMultiError string = "multi"
CodeMultiError string = "multiple-errors"
CodeParamError string = "param"
@ -47,7 +48,7 @@ const (
var (
G = struct {
Formatter efmt.ErrorFormatter
Formatter fmtr.ErrorFormatter
ErrParam ErrCode
ErrParamNil ErrCode
@ -59,7 +60,7 @@ var (
ErrParamNil : ErrCode(CodeParamNilError),
ErrParamOutOfRange : ErrCode(CodeParamOutOfRangeError),
Formatter : err_text_fmt.DefaultFormatter(),
Formatter : ftext.NewFormatter(),//err_text_fmt.DefaultFormatter(),
}
g = struct {
@ -88,9 +89,9 @@ func ToErr (err any) error {
func ToFormat (err error, formatter efmt.ErrorFormatter) string {
if formatter != nil {
return string(formatter.Format(err))
return string(formatter.FormatError(err))
}
return string(G.Formatter.Format(err))
return string(G.Formatter.FormatError(err))
}

@ -33,14 +33,13 @@ type (
Builder interface {
AddHead (errStr, errType string)
AddFieldString (name string, value string )
AddFieldInt (name string, value int )
AddFieldFloat (name string, value float64 )
AddFieldBool (name string, value bool )
AddFieldTime (name string, value time.Time)
AddFieldDate (name string, value time.Time)
AddText (str string)
BuildString(name string, value string )
BuildInt(name string, value int )
BuildFloat(name string, value float64 )
BuildBool(name string, value bool )
BuildTime(name string, value time.Time)
BuildDate(name string, value time.Time)
}
)

@ -70,5 +70,5 @@ func (s BuilderOption) ShowCause () bool {
func (s BuilderOption) ShowTrace () bool {
return s&ShowTrace !=0 }
func (s BuilderOption) ShowFieldEmpty () bool {
func (s BuilderOption) ShowFieldEmpty() bool {
return s&ShowFieldEmpty !=0 }

@ -91,7 +91,7 @@ func (e ErrBuilder) StackTrace () stack.Trace {
func (e ErrBuilder) BuildFormat (builder Builder) {
builder.AddHead(e.Error(),"core.errs.erfmt.ErrBuilder")
if len(e.message) > 0 {
builder.AddFieldString(FieldNameMessage,e.message)
builder.BuildString(FieldNameMessage,e.message)
}
}

@ -74,7 +74,7 @@ func NewTextFormatter(options ...TextFormatterFnc) *TextFormatter {
func (f *TextFormatter) Format (err error) []byte {
func (f *TextFormatter) FormatError(err error) []byte {
if err == nil {
return nil
}

@ -73,6 +73,29 @@ func (s *state) reset () *state {
}
func (s *state) wError (err error, level int) (fe error) {
if er,is := err.(efmt.Buildable); is {
er.BuildFormat(s)
return
}
rt := reflect.TypeOf(err)
if rt.Kind() == reflect.Pointer {
rt = rt.Elem()
}
eb := efmt.GetErrorTypeBuilder(rt)
if eb != nil {
eb.BuildError(s,err)
return
}
eb = efmt.MakeErrorTypeBuilder(s,err)
efmt.SetErrorTypeBuilder(rt,eb)
return
}
func (s *state) writeError(err error, addUnwrap, addCause, addTrace bool, level int) (fe error) {
d := false
@ -90,26 +113,11 @@ func (s *state) writeError(err error, addUnwrap, addCause, addTrace bool, level
}
}(s,&d,&fe)
if fe,is := err.(efmt.Buildable); is {
fe.BuildFormat(s)
} else {
rt := reflect.TypeOf(err)
if rt.Kind() == reflect.Pointer {
rt = rt.Elem()
}
eb := efmt.GetErrorTypeBuilder(rt)
if eb != nil {
eb.BuildError(s,err)
} else {
eb := efmt.MakeErrorTypeBuilder(s,err)
efmt.SetErrorTypeBuilder(rt,eb)
}
}
s.wError(err,level)
if s.unwrap {
s.unwrap = false
d = true
return fe
return
}
if addUnwrap {
@ -138,7 +146,7 @@ func (s *state) writeError(err error, addUnwrap, addCause, addTrace bool, level
func (s *state) writeUnwrap(err error, level int) {
uw := errors.Unwrap(err)
for uw != nil {
if ue := s.writeError(uw,true,false,false, level); ue != nil {
if ue := s.wError(uw, level); ue != nil {
// llamamos al fallback del formateador
s.AddText(s.f.fbOnUnwrap(uw))
}
@ -156,16 +164,19 @@ func (s *state) writeCause(err error, level int ) {
nx := err
dn := false
ps := s.b.Len()
if s.curSec <= 1 {
s.curSec = 2
s.setAnsi(s.f.sections.Cause.Ansi)
s.f.sections.Cause.doBefore(s)
dn = true
}
for nx != nil {
if cs, is := err.(interface{ Cause() error }); is {
if ce := cs.Cause(); ce != nil {
if s.curSec <= 1 {
s.curSec = 2
s.setAnsi(s.f.sections.Cause.Ansi)
s.f.sections.Cause.doBefore(s)
dn = true
}
s.curSec = 0
if fe := s.writeError(ce, false, true, false, level+1); fe != nil {
// llamamos al fallback del formateador
@ -182,14 +193,11 @@ func (s *state) writeCause(err error, level int ) {
lc = me.Unwrap()
}
if len(lc) > 0 {
if s.curSec == 1 {
s.curSec = 2
s.setAnsi(s.f.sections.Cause.Ansi)
s.f.sections.Cause.doBefore(s)
dn = true
}
for _, e := range lc {
if fe := s.writeError(e, false, false, false, level); fe != nil {
for i, e := range lc {
fmt.Printf("Error Cauyse %d\n",i)
s.curSec = 0
s.unwrap = false
if fe := s.wError(e, level); fe != nil {
s.AddText(fmt.Sprintf(fbCauseError, reflect.TypeOf(e), fe.Error()))
}
}
@ -201,6 +209,8 @@ func (s *state) writeCause(err error, level int ) {
if dn {
s.f.sections.Cause.doAfter(s)
} else {
s.b.Truncate(ps)
}
}
@ -272,7 +282,7 @@ func (s *state) AddText(str string) {
s.writeString(str) }
func (s *state) AddHead(errStr, errType string) {
if s.curSec > 0 {
if s.unwrap || s.curSec > 0 {
return
}
s.ansi = s.f.sections.Head.Ansi
@ -284,42 +294,42 @@ func (s *state) AddHead(errStr, errType string) {
}
func (s *state) AddFieldString (name string, value string ) {
func (s *state) BuildString(name string, value string ) {
if s.curSec != 1 {
return
}
s.writeField(name,value,false)
}
func (s *state) AddFieldInt (name string, value int ) {
func (s *state) BuildInt(name string, value int ) {
if s.curSec != 1 {
return
}
s.writeField(name,fmt.Sprintf(s.f.vLayouts.intLayout,value),false)
}
func (s *state) AddFieldFloat (name string, value float64 ) {
func (s *state) BuildFloat(name string, value float64 ) {
if s.curSec != 1 {
return
}
s.writeField(name,fmt.Sprintf(s.f.vLayouts.floatLayout,value),false)
}
func (s *state) AddFieldBool (name string, value bool ) {
func (s *state) BuildBool(name string, value bool ) {
if s.curSec != 1 {
return
}
s.writeField(name,fmt.Sprintf(s.f.vLayouts.boolLayout,value),false)
}
func (s *state) AddFieldTime (name string, value time.Time) {
func (s *state) BuildTime(name string, value time.Time) {
if s.curSec != 1 {
return
}
s.writeField(name,value.Format(s.f.vLayouts.timeLayout),false)
}
func (s *state) AddFieldDate (name string, value time.Time) {
func (s *state) BuildDate(name string, value time.Time) {
if s.curSec != 1 {
return
}

@ -29,7 +29,7 @@ type (
ErrorFormatter interface {
Format(err error) []byte
FormatError(err error) []byte
}
@ -37,6 +37,6 @@ type (
)
func (f FormatErrorFnc) Format(err error) []byte {
func (f FormatErrorFnc) FormatError(err error) []byte {
return f(err) }

@ -25,6 +25,7 @@ package errs
import (
"errs/efmt"
"errs/fmtr"
)
type (
@ -66,12 +67,13 @@ func (e ErrCause) WrapWithTrace(offset int) error {
func (e ErrCause) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }
func (e ErrCause) BuildFormat (builder efmt.Builder) {
builder.AddHead(e.Error(),"core.errs.ErrCause")
}
func (e ErrCause) Format (builder fmtr.Builder) {
builder.Build(e.Error(),"core.errs.ErrCause",nil) }

@ -25,6 +25,7 @@ package errs
import (
"errs/efmt"
"errs/fmtr"
)
type (
@ -68,9 +69,13 @@ func (e ErrCode) WrapWithTrace(offset int) error {
func (e ErrCode) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }
func (e ErrCode) BuildFormat (builder efmt.Builder) {
builder.AddHead(string(e),"core.errs.ErrCode")
}
}
func (e ErrCode) Format (builder fmtr.Builder) {
builder.Build(string(e),"core.errs.ErrCode",nil) }

@ -26,6 +26,7 @@ package errs
import (
"errs/efmt"
"errs/fmtr"
"fmt"
"time"
)
@ -95,26 +96,37 @@ func (e ErrInfo) WrapWithTrace(offset int) error {
func (e ErrInfo) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }
func (e ErrInfo) BuildFormat (builder efmt.Builder) {
builder.AddHead(e.Error(),"core.errs.ErrInfo")
builder.AddFieldString("message",e.message)
builder.AddFieldString("info",e.info)
builder.AddFieldTime ("date",e.date)
builder.BuildString("message",e.message)
builder.BuildString("info",e.info)
builder.BuildTime("date",e.date)
if len(e.metas) > 0 {
for n,v := range e.metas {
builder.AddFieldString(n,v)
builder.BuildString(n,v)
}
}
}
func (e ErrInfo) Format (builder fmtr.Builder) {
builder.Build(e.Error(),"core.errs.ErrInfo",func (fb fmtr.FieldBuilder){
fb.AddString("message",e.message)
fb.AddString("info",e.info)
fb.AddDate ("date",e.date)
if len(e.metas) > 0 {
for n,v := range e.metas {
fb.AddString(n,v)
}
}
})
}

@ -25,6 +25,7 @@ package errs
import (
"errs/efmt"
"errs/fmtr"
)
type (
@ -69,13 +70,14 @@ func (e ErrMulti) WrapWithTrace(offset int) error {
func (e ErrMulti) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }
func (e ErrMulti) BuildFormat (builder efmt.Builder) {
builder.AddHead(CodeMultiError,"core.errs.ErrMulti") }
func (e ErrMulti) Format (builder fmtr.Builder) {
builder.Build(e.Error(),"core.errs.ErrMulti",nil) }

@ -23,7 +23,10 @@
package errs
import "errs/efmt"
import (
"errs/efmt"
"errs/fmtr"
)
type (
@ -63,9 +66,12 @@ func (e ErrPanic) WrapWithTrace(offset int) error {
func (e ErrPanic) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }
func (e ErrPanic) BuildFormat (builder efmt.Builder) {
builder.AddHead (CodePanicError,"core.errs.ErrPanic")
}
}
func (e ErrPanic) Format (builder fmtr.Builder) {
builder.Build(e.Error(),"core.errs.ErrPanic",nil) }

@ -25,6 +25,7 @@ package errs
import (
"errs/efmt"
"errs/fmtr"
"fmt"
)
@ -75,13 +76,20 @@ func (e ErrParam) WrapWithTrace(offset int) error {
func (e ErrParam) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }
func (e ErrParam) BuildFormat (builder efmt.Builder) {
builder.AddHead(e.code,"core.errs.ErrParam")
if len(e.message) > 0 {
builder.AddFieldString(efmt.FieldNameMessage, e.message)
builder.BuildString(efmt.FieldNameMessage, e.message)
}
}
func (e ErrParam) Format (builder fmtr.Builder) {
builder.Build(e.Error(),"core.errs.ErrParam",func (fb fmtr.FieldBuilder){
if len(e.message) > 0 && e.message != e.Error() {
fb.AddString(fmtr.FieldNameMessage,e.message)
}
}) }

@ -25,6 +25,7 @@ package errs
import (
"errs/efmt"
"errs/fmtr"
"errs/stack"
)
@ -78,9 +79,14 @@ func (e ErrTrace) WrapWithCause(cause error) error {
func (e ErrTrace) String () string {
return string(G.Formatter.Format(e)) }
return string(G.Formatter.FormatError(e)) }
func (e ErrTrace) BuildFormat (builder efmt.Builder) {
builder.AddHead(e.Error(),"core.errs.ErrTrace")
}
func (e ErrTrace) Format (builder fmtr.Builder) {
builder.Build(e.Error(),"core.errs.ErrTrace",nil) }

@ -0,0 +1,139 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name active.go
// Created by DEV
// Modified 09/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
import (
"reflect"
"sync"
)
const (
CodeBuilderError string = "build-format"
CodeBuilderLevelError string = "builder-invalid-level"
fmtErrorFormatUnwrap string = "cant unwrap error type %s"
fmtErrorTypeFormat string = "cant build format for error type %s"
)
const (
FieldNameError string = "error"
FieldNameCode string = "code"
FieldNameType string = "type"
FieldNameMessage string = "message"
FieldNameInfo string = "info"
FieldNameDate string = "date"
FieldNameTime string = "time"
FieldNameParam string = "param"
FieldNameSource string = "source"
FieldNameUser string = "user"
)
var (
g = struct {
mux sync.RWMutex
builders map[reflect.Type]ErrorBuilder
collectors FieldCollectors
}{
builders : make(map[reflect.Type]ErrorBuilder),
collectors : defaultCollectors(),
}
)
func GetErrorTypeBuilder(rtype reflect.Type) ErrorBuilder {
g.mux.RLock()
b,_ := g.builders[rtype]
g.mux.RUnlock()
return b
}
func SetErrorTypeBuilder(rtype reflect.Type, errBuilder ErrorBuilder) {
if rtype == nil {
return
}
g.mux.Lock()
if errBuilder == nil {
delete(g.builders,rtype)
} else {
g.builders[rtype] = errBuilder
}
g.mux.Unlock()
}
func MakeErrorTypeBuilder(builder Builder, err error) ErrorBuilder {
var eb FieldCollectors
g.mux.RLock()
defer g.mux.RUnlock()
builder.Build(err.Error(),reflect.TypeOf(err).String(), func(fb FieldBuilder){
for _,c := range g.collectors {
if c.CollectField(fb,err) {
eb = append(eb,c)
}
}
})
if len(eb) == 0 {
return BuildErrorFnc(BasicBuildError)
}
return eb
}
func AddCollector (collector FieldCollector) {
if collector == nil {
return
}
g.mux.Lock()
g.collectors = append(g.collectors,collector)
g.mux.Unlock()
}
func defaultCollectors () FieldCollectors {
return FieldCollectors{
}
}

@ -0,0 +1,43 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name builder.go
// Created by DEV
// Modified 15/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
type (
Builder interface {
Build(errCode, errType string, fbuilder BuildFieldFnc)
}
BuildFnc func(errCode, errType string, fbuilder BuildFieldFnc)
)
func (f BuildFnc) Build(errCode, errType string, fbuilder BuildFieldFnc) {
f(errCode,errType,fbuilder) }

@ -0,0 +1,41 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name collector.go
// Created by DEV
// Modified 09/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
type (
FieldCollector interface {
CollectField (builder FieldBuilder, err error) bool
}
CollectFieldFnc func (builder FieldBuilder, err error) bool
)
func (f CollectFieldFnc) CollectField(builder FieldBuilder, err error) bool {
return f(builder,err) }

@ -0,0 +1,66 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name field_collectors.go
// Created by DEV
// Modified 09/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
import "reflect"
type (
FieldCollectors []FieldCollector
)
func (f FieldCollectors) BuildError(builder Builder, err error) {
builder.Build(err.Error(),reflect.TypeOf(err).String(), func(fb FieldBuilder) {
f.CollectField(fb,err)
})
}
func (f FieldCollectors) MakeErrorBuilder (builder Builder, err error) ErrorBuilder {
var eb FieldCollectors
builder.Build(err.Error(),reflect.TypeOf(err).String(),func(fb FieldBuilder){
for _,c := range f {
if c.CollectField(fb,err) {
eb = append(eb,c)
}
}
})
if len(eb) == 0 {
return BuildErrorFnc(BasicBuildError)
}
return eb
}
func (f FieldCollectors) CollectField (builder FieldBuilder, err error) bool {
r := true
for _,fc := range f {
r = r && fc.CollectField(builder,err)
}
return r
}

@ -0,0 +1,98 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name err_format.go
// Created by DEV
// Modified 10/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
import (
"errs/stack"
"fmt"
"reflect"
)
type (
ErrBuilder struct {
code string
message string
cause error
trace stack.Trace
}
)
func NewErrBuilder(code string, cause error, message string, addTrace bool) *ErrBuilder {
var tc stack.Trace
if addTrace {
tc = stack.MakeStackTrace(3)
}
return &ErrBuilder{
code : code,
cause : cause,
message: message,
trace : tc,
}
}
func NewErrBuilderFormat (cause error, rtype reflect.Type, addTrace bool) *ErrBuilder {
return NewErrBuilder(CodeBuilderError,cause,fmt.Sprintf(fmtErrorTypeFormat,rtype.String()),addTrace) }
func NewErrBuilderUnwrap (cause error, rtype reflect.Type, addTrace bool) *ErrBuilder {
return NewErrBuilder(CodeBuilderError,cause,fmt.Sprintf(fmtErrorFormatUnwrap,rtype.String()),addTrace) }
func NewErrBuildLevel() *ErrBuilder {
return &ErrBuilder{ code : CodeBuilderLevelError} }
func (e ErrBuilder) Code () string {
return e.code }
func (e ErrBuilder) Error() string {
return e.code }
func (e ErrBuilder) Cause() error {
return e.cause }
func (e ErrBuilder) Message() string {
return e.message }
func (e ErrBuilder) StackTrace () stack.Trace {
return e.trace }
func (e ErrBuilder) BuildFormat (builder Builder) {
builder.Build(e.Error(),"core.errs.efmtr.ErrBuilder",func (fb FieldBuilder){
if len(e.message) > 0 {
fb.AddString(FieldNameMessage,e.message)
}
})
}

@ -0,0 +1,47 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name error_format_builder.go
// Created by DEV
// Modified 15/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
import "reflect"
type (
ErrorBuilder interface {
BuildError(builder Builder, err error)
}
BuildErrorFnc func (builder Builder, err error)
)
func (f BuildErrorFnc) BuildError(builder Builder, err error) {
f(builder,err) }
func BasicBuildError (builder Builder, err error) {
builder.Build(err.Error(),reflect.TypeOf(err).String(),nil) }

@ -0,0 +1,39 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name ErrorFormatter.go
// Created by DEV
// Modified 15/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
type (
ErrorFormatter interface {
FormatError(err error) []byte
}
FormatErrorFnc func (err error) []byte
)
func (f FormatErrorFnc) FormatError(err error) []byte {
return f(err) }

@ -0,0 +1,71 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name builder.go
// Created by DEV
// Modified 15/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
import "time"
type (
FieldBuilder interface {
AddAny (name string, value any )
AddInt (name string, value int )
AddBool (name string, value bool )
AddString(name string, value string )
AddFloat (name string, value float64)
AddTime (name string, value time.Time)
AddDate (name string, value time.Time)
}
BuildFieldFnc func (builder FieldBuilder)
)
func AddAny(name string, value any) BuildFieldFnc {
return func(b FieldBuilder) {
b.AddAny(name,value) }}
func AddString(name, value string) BuildFieldFnc {
return func(b FieldBuilder) {
b.AddString(name,value) }}
func AddInt (name string, value int) BuildFieldFnc {
return func(b FieldBuilder) {
b.AddInt(name,value) }}
func AddFloat(name string, value float64) BuildFieldFnc {
return func(b FieldBuilder) {
b.AddFloat(name,value) }}
func AddBool (name string, value bool) BuildFieldFnc {
return func(b FieldBuilder) {
b.AddBool(name,value) }}
func AddTime (name string, value time.Time) BuildFieldFnc {
return func(b FieldBuilder) {
b.AddTime(name,value) }}
func AddDate (name string, value time.Time) BuildFieldFnc {
return func(b FieldBuilder) {
b.AddDate(name,value) }}

@ -0,0 +1,36 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name format_buildable.go
// Created by DEV
// Modified 15/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fmtr
type (
Formattable interface {
Format(builder Builder)
}
)

@ -0,0 +1,26 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name active.go
// Created by DEV
// Modified 16/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext

@ -0,0 +1,67 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name formtter.go
// Created by DEV
// Modified 16/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import "atypes/astrings"
type (
Formatter struct {
option
lays layouts
secs Sections
nameTrans ,
valueTrans,
stringTrans astrings.Transformers
}
FormatterFnc func (formatter *Formatter)
)
func NewFormatter (options ...FormatterFnc) *Formatter {
fm := &Formatter {
option: optionsDefault,
lays: *newLayouts(),
}
return fm
}
func (f *Formatter) FormatError (err error) []byte {
s := newState(f)
if fe := s.format(err); fe != nil {
}
return s.b.Bytes()
}

@ -0,0 +1,55 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name layouts.go
// Created by DEV
// Modified 13/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import (
"time"
)
type (
layouts struct {
sep string
indent string
timeLayout string
dateLayout string
intLayout string
floatLayout string
boolLayout string
}
)
func newLayouts () *layouts {
return &layouts{
indent : " ",
sep : " : ",
timeLayout : time.RFC822Z,
dateLayout : time.RFC822Z,
intLayout : "%d",
floatLayout : "%-10s: %.2f",
}
}

@ -0,0 +1,76 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name show.go
// Created by DEV
// Modified 07/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
const (
ShowWrapped option = 1 << iota
ShowType
ShowAnsi
ShowIndent
ShowFields
ShowCause
ShowTrace
NotShowEmpty
optionsDefault = ShowWrapped | ShowType | ShowAnsi | ShowIndent | ShowFields | ShowCause | ShowTrace | NotShowEmpty
)
type (
option uint8
)
func (s option) SetDefaults () option {
return optionsDefault
}
func (s option) ShowWrapped () bool {
return s&ShowWrapped !=0 }
func (s option) ShowType () bool {
return s&ShowType !=0 }
func (s option) ShowAnsi () bool {
return s&ShowAnsi !=0 }
func (s option) ShowIndent () bool {
return s&ShowIndent !=0 }
func (s option) ShowFields() bool {
return s&ShowFields !=0 }
func (s option) ShowCause () bool {
return s&ShowCause !=0 }
func (s option) ShowTrace () bool {
return s&ShowTrace !=0 }
func (s option) NotShowEmpty() bool {
return s&NotShowEmpty !=0 }

@ -0,0 +1,45 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name section.go
// Created by DEV
// Modified 16/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import "ansi"
type (
Section struct {
Ansi ansi.Code
}
)
func (s Section) Begin () {
}
func (s Section) End () {
}

@ -0,0 +1,38 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name sections.go
// Created by DEV
// Modified 16/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
type (
Sections struct {
Main Section
Head Section
Fields Section
Cause Section
Trace Section
}
)

@ -0,0 +1,279 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name formatter_stae.go
// Created by DEV
// Modified 16/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import (
"ansi"
"bytes"
"errors"
"errs/fmtr"
"fmt"
"reflect"
"strings"
"time"
)
type (
state struct {
f *Formatter
b bytes.Buffer
section *Section
level int
ansiC ansi.Code
unwrap bool
}
)
func newState(formatter *Formatter) *state {
return &state{
f : formatter,
}
}
func (s *state) format (err error) (fe error) {
if fe = s.wError(err,0); fe != nil {
return fe
}
if fe = s.wCause(err,0); fe != nil {
}
return
}
func (s *state) wError (err error, level int) (fe error) {
if err == nil {
return
}
if s.level != level && !s.unwrap {
ol := s.level
s.level = level
defer func(){ s.level = ol }()
}
if eb,is := err.(fmtr.Formattable); is {
eb.Format(s)
} else {
rt := reflect.TypeOf(err)
if rt.Kind() == reflect.Pointer {
rt = rt.Elem()
}
eb := fmtr.GetErrorTypeBuilder(rt)
if eb != nil {
eb.BuildError(s,err)
return
}
eb = fmtr.MakeErrorTypeBuilder(s,err)
fmtr.SetErrorTypeBuilder(rt,eb)
}
if !s.unwrap {
s.unwrap = true
}
if fe = s.wError(errors.Unwrap(err), level); fe != nil {
return fe
}
s.unwrap = false
return fe
}
func (s *state) wCause(err error, level int ) (fe error){
nx := err
for nx != nil {
if cs, is := nx.(interface{ Cause() error }); is {
if ce := cs.Cause(); ce != nil {
s.b.WriteString("-Prev Cause --------------------\n")
if fe := s.wError(ce, level+1); fe != nil {
// llamamos al fallback del formateador
}
nx = errors.Unwrap(ce)
continue
}
}
var lc []error
if cs, is := nx.(interface{ Causes() []error }); is {
lc = cs.Causes()
} else if me, ok := nx.(interface{ Unwrap() []error }); ok {
lc = me.Unwrap()
}
if len(lc) > 0 {
for i, e := range lc {
s.b.WriteString(fmt.Sprintf("-%d---------------\n",i))
if fe = s.wError(e,level+1); fe != nil {
// llamamos al fallback del formateado
}
if fe = s.wCause(e,level+1); fe != nil {
}
}
return
}
nx = errors.Unwrap(nx)
}
return
}
func getCauses (err error) []error {
if err == nil {
return nil
}
if cs,is := err.(interface { Cause() error }); is {
ce := cs.Cause()
if ce == nil {
return nil
}
return []error{ce}
}
if cs,is := err.(interface { Causes() []error }); is {
return cs.Causes()
}
if cs,is := err.(interface{ Unwrap() []error }); is {
return cs.Unwrap()
}
return nil
}
func (s *state) applySection (sec *Section, begin bool) {
if begin {
s.section = sec
s.section.Begin()
}
}
func (s *state) indent () string {
if s.level == 0 {
return ""
}
return strings.Repeat(s.f.lays.indent,s.level)
}
func (s *state) Build(errCode, errType string, fbuilder fmtr.BuildFieldFnc) {
if !s.unwrap {
s.applySection(&s.f.secs.Head,true)
s.writeField(fmtr.FieldNameError,errCode)
if s.f.ShowType() {
s.writeField(fmtr.FieldNameType, errType)
}
s.applySection(&s.f.secs.Head,false)
}
if fbuilder != nil {
s.applySection(&s.f.secs.Fields,true)
fbuilder(s)
}
}
func (s *state) AddAny (name string, value any ) {
if value == nil && s.f.NotShowEmpty() {
return
}
}
func (s *state) AddInt (name string, value int ) {
s.writeField(name,fmt.Sprintf(s.f.lays.intLayout,value))}
func (s *state) AddBool (name string, value bool ) {
s.writeField(name,fmt.Sprintf(s.f.lays.boolLayout)) }
func (s *state) AddString(name string, value string ) {
if len(value) == 0 && s.f.NotShowEmpty() {
return
}
s.writeField(name,value) }
func (s *state) AddFloat (name string, value float64) {
s.writeField(name,fmt.Sprintf(s.f.lays.floatLayout,value)) }
func (s *state) AddTime (name string, value time.Time) {
if value.IsZero() && s.f.NotShowEmpty() {
return
}
s.writeField(name,value.Format(s.f.lays.timeLayout)) }
func (s *state) AddDate (name string, value time.Time) {
if value.IsZero() && s.f.NotShowEmpty() {
return
}
s.writeField(name,value.Format(s.f.lays.dateLayout)) }
func (s *state) writeField (name string, value string) {
n := s.f.nameTrans.Apply(name)
v := s.f.valueTrans.Apply(value)
s.b.WriteString(s.indent())
if s.ansiC == 0 {
s.b.WriteString(n)
s.b.WriteString(s.f.lays.sep)
s.b.WriteString(v)
s.b.WriteByte('\n')
return
}
s.b.WriteString(s.ansiC.String())
s.b.WriteString(n)
s.b.WriteString(s.f.lays.sep)
s.b.WriteString(v)
s.b.WriteByte('\n')
s.b.WriteString(s.ansiC.End())
}
Loading…
Cancel
Save

Powered by TurnKey Linux.