seguims con los errores

master
DEV 3 years ago
parent d43d13c37f
commit 70814fe835

@ -126,6 +126,21 @@ func Unwrap(err error) error {
}
func UnwrapCause(err error) error {
e := err
for e != nil {
cs,is := e.(Causer)
if is {
return cs.Cause()
}
e = Unwrap(e)
}
return nil
}
func UnwrapList(err error) ErrorList {
if err == nil {
return nil

@ -73,15 +73,3 @@ func (e ErrCause) BuildFormat (builder erfmt.Builder) {
func UnwrapCause(err error) error {
e := Unwrap(err)
for e != nil {
cs,is := e.(Causer)
if is {
return cs.Cause()
}
e = Unwrap(e)
}
return nil
}

@ -71,7 +71,7 @@ var (
func GetErrorBuilder (rtype reflect.Type) ErrorBuilder {
func GetErrorTypeBuilder(rtype reflect.Type) ErrorBuilder {
g.mux.RLock()
b,_ := g.builders[rtype]
g.mux.RUnlock()
@ -79,7 +79,7 @@ func GetErrorBuilder (rtype reflect.Type) ErrorBuilder {
}
func SetErrorBuilder (rtype reflect.Type, errBuilder ErrorBuilder) {
func SetErrorTypeBuilder(rtype reflect.Type, errBuilder ErrorBuilder) {
if rtype == nil {
return
}
@ -93,7 +93,7 @@ func SetErrorBuilder (rtype reflect.Type, errBuilder ErrorBuilder) {
}
func MakeErrorBuilder (builder Builder, err error) ErrorBuilder {
func MakeErrorTypeBuilder(builder Builder, err error) ErrorBuilder {
builder.AddHead(err.Error(),reflect.TypeOf(err).String())
var eb FieldCollectors
@ -117,7 +117,9 @@ func AddCollector (collector FieldCollector) {
if collector == nil {
return
}
g.mux.Lock()
g.collectors = append(g.collectors,collector)
g.mux.Unlock()
}

@ -0,0 +1,73 @@
// ------------------------------------------------------------------------
// 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 err_fmt
const (
ShowWrapped BuilderOption = 1 << iota
ShowType
ShowAnsi
ShowIndent
ShowFields
ShowCause
ShowTrace
ShowFieldEmpty
showDefault = ShowWrapped | ShowType | ShowAnsi | ShowIndent | ShowFields | ShowCause | ShowTrace
)
type (
BuilderOption uint8
)
func (s BuilderOption) SetDefaults () BuilderOption {
return showDefault }
func (s BuilderOption) ShowWrapped () bool {
return s&ShowWrapped !=0 }
func (s BuilderOption) ShowType () bool {
return s&ShowType !=0 }
func (s BuilderOption) ShowAnsi () bool {
return s&ShowAnsi !=0 }
func (s BuilderOption) ShowIndent () bool {
return s&ShowIndent !=0 }
func (s BuilderOption) ShowFields() bool {
return s&ShowFields !=0 }
func (s BuilderOption) ShowCause () bool {
return s&ShowCause !=0 }
func (s BuilderOption) ShowTrace () bool {
return s&ShowTrace !=0 }
func (s BuilderOption) ShowFieldEmpty () bool {
return s&ShowFieldEmpty !=0 }

@ -0,0 +1,38 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name field.go
// Created by DEV
// Modified 12/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 fmx
type (
field struct {
n string
v string
f
}
)

@ -0,0 +1,45 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name fmt.go
// Created by DEV
// Modified 12/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 fmx
type (
TextErrorFormatter struct {}
)
func (f *TextErrorFormatter) Format (err error) []byte {
st := &state{
f : f,
}
er :=
}

@ -0,0 +1,49 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name section.go
// Created by DEV
// Modified 12/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 fmx
import (
"ansi"
"errs/err_fmt"
)
type (
section struct {
code ansi.Code
before err_fmt.BuildFnc
after err_fmt.BuildFnc
}
)
func (s *section) doBefore (b err_fmt.Builder) {
if s != nil && s.before != nil {
s.before.Build(b) } }
func (s *section) doAfter (b err_fmt.Builder) {
if s != nil && s.after != nil {
s.after.Build(b) } }

@ -0,0 +1,120 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name state.go
// Created by DEV
// Modified 12/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 fmx
import (
"bytes"
"errors"
"errs/err_fmt"
"errs/stack"
"reflect"
)
type (
state struct {
f *TextErrorFormatter
b bytes.Buffer
secs []*section
flds []field
cses []error
trace stack.Trace
}
)
func newState (f *TextErrorFormatter) *state {
return &state {
f : f,
}
}
func (s *state) format (err error, unwrapping bool) (fe error) {
if fe,is := err.(err_fmt.Buildable); is {
fe.Build(s)
} else {
rt := reflect.TypeOf(err)
if rt.Kind() == reflect.Pointer {
rt = rt.Elem()
}
eb := err_fmt.GetErrorTypeBuilder(rt)
if eb != nil {
eb.BuildError(s,err)
} else {
eb := err_fmt.MakeErrorTypeBuilder(s,err)
err_fmt.SetErrorTypeBuilder(rt,eb)
}
}
if unwrapping {
return fe
}
return nil
}
func (s *state) unwrapError (err error) {
uw := errors.Unwrap(err)
for uw != nil {
if ue := s.format(uw,true); ue != nil {
}
}
}

@ -21,15 +21,20 @@
// limitations under the License.
// ------------------------------------------------------------------------
package err_fmt
package txt
import "atypes/astrings"
import (
"atypes/astrings"
"errs/err_fmt"
)
type (
TextFmt struct {
options err_fmt.BuilderOption
timeLayout string
dateLayout string
intLayout string
@ -40,21 +45,23 @@ type (
valueTrans astrings.Transformers
stringTrans astrings.Transformers
defSec *textFmtSection
headSec *textFmtSection
fieldsSec *textFmtSection
causeSec *textFmtSection
multiSec *textFmtSection
traceSec *textFmtSection
defSec *err_fmt.textFmtSection
headSec *err_fmt.textFmtSection
fieldsSec *err_fmt.textFmtSection
causeSec *err_fmt.textFmtSection
multiSec *err_fmt.textFmtSection
traceSec *err_fmt.textFmtSection
fieldFormats map[string]*err_fmt.textFmtFieldFormat
fmeBuilder FrameBuilder
fmeBuilder err_fmt.FrameBuilder
}
)
func (f *TextFmt) Format (err error) []byte {
st := state{
st := err_fmt.state{
}
@ -66,3 +73,7 @@ func (f *TextFmt) Format (err error) []byte {
}
func (f *TextFmt) getFieldFormat (name string) *err_fmt.textFmtFieldFormat {
fl,_ := f.fieldFormats[name]
return fl
}

@ -0,0 +1,41 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name text_fmt_field.go
// Created by DEV
// Modified 11/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 txt
type (
textFmtField struct {
name string
value string
format *textFmtFieldFormat
}
)
func newTextFmtField (name, value string, format *textFmtFieldFormat) *textFmtField {
return &textFmtField{
name : name,
value : value,
format: format }
}

@ -0,0 +1,55 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name text_fmt_field_format.go
// Created by DEV
// Modified 11/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 txt
import (
"ansi"
"atypes/astrings"
"errs/erfmt"
)
type (
textFmtFieldFormat struct {
NameAnsi ansi.Code
ValueAnsi ansi.Code
NameTrans astrings.Transformers
ValueTrans astrings.Transformers
BuildBefore erfmt.FormattableFnc
BuildAfter erfmt.FormattableFnc
}
)
func (f textFmtFieldFormat) clone() textFmtFieldFormat {
return textFmtFieldFormat{
NameAnsi: f.NameAnsi,
ValueAnsi: f.ValueAnsi,
NameTrans: append(astrings.Transformers(nil),f.NameTrans...),
ValueTrans: append(astrings.Transformers(nil),f.ValueTrans...),
}
}

@ -21,21 +21,24 @@
// limitations under the License.
// ------------------------------------------------------------------------
package err_fmt
package txt
import "ansi"
import (
"ansi"
"errs/err_fmt"
)
type (
textFmtSection struct {
ansi ansi.Code
beginFn BuildFnc
endFn BuildFnc
ansi ansi.Code
beginFn err_fmt.BuildFnc
endFn err_fmt.BuildFnc
}
)
func (s *textFmtSection) begin (b Builder) {
func (s *textFmtSection) begin (b err_fmt.Builder) {
if s == nil {
return
}
@ -44,7 +47,7 @@ func (s *textFmtSection) begin (b Builder) {
}
}
func (s *textFmtSection) end (b Builder) {
func (s *textFmtSection) end (b err_fmt.Builder) {
if s == nil {
return
}

@ -21,10 +21,12 @@
// limitations under the License.
// ------------------------------------------------------------------------
package err_fmt
package txt
import (
"bytes"
"errors"
"errs/err_fmt"
"errs/stack"
"fmt"
"reflect"
@ -34,23 +36,30 @@ import (
type (
state struct {
f TextFmt
b bytes.Buffer
f TextFmt
b bytes.Buffer
doHead bool
doFields bool
doUnwrap bool
doCause bool
doTrace bool
head [2]textFmtField
fields []textFmtField
trace []byte
}
)
func newState (fmt TextFmt) *state {
return &state {
return &state{
f : fmt,
doHead : true,
doFields: fmt.options.ShowFields(),
doUnwrap: fmt.options.ShowWrapped(),
doCause : fmt.options.ShowCause(),
doTrace : fmt.options.ShowTrace(),
}
}
@ -60,8 +69,8 @@ func (s *state) AddHead(code, errType string) {
s.doHead = false
s.doFields = true
s.f.headSec.begin(s)
s.AddFieldString(FieldNameError,code)
s.AddFieldString(FieldNameType ,errType)
s.head[0]=*newTextFmtField(err_fmt.FieldNameError,code,s.f.getFieldFormat(err_fmt.FieldNameError))
s.head[1]=*newTextFmtField(err_fmt.FieldNameType,errType,s.f.getFieldFormat(err_fmt.FieldNameType))
s.f.headSec.end(s)
}
}
@ -69,23 +78,51 @@ func (s *state) AddHead(code, errType string) {
func (s *state) AddFieldInt (name string, value int ) {
s.AddFieldString(name,fmt.Sprintf(s.f.intLayout,value)) }
s.addField(name,fmt.Sprintf(s.f.intLayout,value)) }
func (s *state) AddFieldBool (name string, value bool ) {
s.AddFieldString(name,fmt.Sprintf(s.f.boolLayout,value)) }
s.addField(name,fmt.Sprintf(s.f.boolLayout,value)) }
func (s *state) AddFieldFloat (name string, value float64 ) {
s.AddFieldString(name,fmt.Sprintf(s.f.floatLayout,value)) }
s.addField(name,fmt.Sprintf(s.f.floatLayout,value)) }
func (s *state) AddFieldTime (name string, value time.Time) {
s.AddFieldString(name,fmt.Sprintf(s.f.timeLayout, value)) }
s.addField(name,fmt.Sprintf(s.f.timeLayout, value)) }
func (s *state) AddFieldDate (name string, value time.Time) {
s.AddFieldString(name,fmt.Sprintf(s.f.dateLayout,value)) }
s.addField(name,fmt.Sprintf(s.f.dateLayout,value)) }
func (s *state) AddFieldString (name, value string) {
if !s.doFields {}
s.addField(name,value) }
func (s *state) addField(name, value string) {
if s.checkField(name) {
s.fields = append(s.fields,*newTextFmtField(name,value,s.f.getFieldFormat(name)))
return
}
c := 1
for {
n := fmt.Sprintf("%s-%d",name,c)
if s.checkField(n) {
s.fields = append(s.fields,*newTextFmtField(n,value,s.f.getFieldFormat(name)))
return
}
}
}
func (s *state) checkField (name string) bool {
for _,f := range s.fields {
if f.name == name {
return false
}
}
return true
}
@ -111,27 +148,26 @@ func (s *state) format (err error, level int, isWrapped, addWrap, addCause, addT
if !is {
ec = fmt.Errorf("%#v",rc)
}
*rs = *NewErrBuilderFormat(ec,reflect.TypeOf(er),true)
*rs = *err_fmt.NewErrBuilderFormat(ec,reflect.TypeOf(er),true)
}
}
}(s,&d,err,&fe)
if fb,is := err.(Buildable); is {
if fb,is := err.(err_fmt.Buildable); is {
fb.Build(s)
} else {
rt := reflect.TypeOf(err)
if rt.Kind() == reflect.Pointer {
rt = rt.Elem()
}
if eb := GetErrorBuilder(rt); eb != nil {
if eb := err_fmt.GetErrorTypeBuilder(rt); eb != nil {
eb.BuildError(s,err)
} else {
eb = MakeErrorBuilder(s,err)
SetErrorBuilder(rt,eb)
eb = err_fmt.MakeErrorTypeBuilder(s,err)
err_fmt.SetErrorTypeBuilder(rt,eb)
}
}
if addWrap {
if uw,is := err.(interface { Unwrap() error }); is {
if ne := uw.Unwrap(); ne != nil {
@ -139,12 +175,55 @@ func (s *state) format (err error, level int, isWrapped, addWrap, addCause, addT
// añadimos un field fmt-(nombre del tipo de error) con el code
// o mensaje de error
rt := reflect.TypeOf(ne).String()
s.AddFieldString(fmt.Sprintf(fmtFieldFormatError,rt),fmt.Sprintf(fmtErrorFormatUnwrap,rt))
s.addField(fmt.Sprintf(err_fmt.fmtFieldFormatError,rt),fmt.Sprintf(err_fmt.fmtErrorFormatUnwrap,rt))
}
}
}
if isWrapped {
return
}
}
s.writeHead ()
s.writeFields()
if addCause {
s.writeCause()
s.writeMulti ()
}
if addTrace {
s.writeTrace()
}
return
}
func (s *state) writeHead () {
s.f.headSec.begin(s)
s.f.headSec.end (s)
}
func (s *state) writeFields () {
if s.f.options.ShowFields() {
s.f.fieldsSec.begin(s)
for i := 0; i < len(s.fields); i++ {
s.writeField(i)
}
s.f.fieldsSec.begin(s)
}
}
func (s *state) writeMulti () {
// MultiErr
if ua,is := err.(interface { Unwrap() []error }); is {
le := ua.Unwrap()
@ -159,57 +238,58 @@ func (s *state) format (err error, level int, isWrapped, addWrap, addCause, addT
// añadimos un field fmt-(nombre del tipo de error) con el code
// o mensaje de error
rt := reflect.TypeOf(el).String()
s.AddFieldString(fmt.Sprintf(fmtFieldFormatError, rt), fmt.Sprintf(fmtErrorTypeFormat, rt))
s.addField(fmt.Sprintf(err_fmt.fmtFieldFormatError, rt), fmt.Sprintf(err_fmt.fmtErrorTypeFormat, rt))
}
}
}
s.f.multiSec.end(s)
}
}
}
func (s *state) writeCause (err error, bool addCause) {
if addCause {
if cs, is := err.(interface{ Cause() error }); is {
if ne := cs.Cause(); ne != nil {
pos:= s.b.Len()
s.f.causeSec.begin(s)
if ec := s.format(ne, level+1, false, addWrap, addCause, addTrace); ec != nil {
// borramos lo incorporado al buffer como precaucion
s.b.Truncate(pos)
// añadimos un field fmt-(nombre del tipo de error) con el code
// o mensaje de error
rt := reflect.TypeOf(ne).String()
s.AddFieldString(fmt.Sprintf(fmtFieldFormatError, rt), fmt.Sprintf(fmtErrorTypeFormat, rt))
}
s.f.causeSec.end(s)
// buscamos entre los wrapped
cc := err
var pe error
for cc != nil {
if cs, is := cc.(interface{ Cause() error }); is {
pe = cs.Cause()
break
}
cc = errors.Unwrap(cc)
}
}
if addTrace {
if tc, is := err.(interface{ stack.Tracer }); is {
if st := tc.StackTrace(); st != nil {
s.doTrace = false
s.f.traceSec.begin(s)
for n,f := range st.Frames() {
s.f.fmeBuilder.BuildFrame(s,f,n)
}
s.f.traceSec.end(s)
if pe != nil {
pos:= s.b.Len()
s.f.causeSec.begin(s)
if ec := s.format(pe, level+1, false, addWrap, addCause, addTrace); ec != nil {
// borramos lo incorporado al buffer como precaucion
s.b.Truncate(pos)
// añadimos un field fmt-(nombre del tipo de error) con el code
// o mensaje de error
rt := reflect.TypeOf(pe).String()
s.addField(fmt.Sprintf(err_fmt.fmtFieldFormatError, rt), fmt.Sprintf(err_fmt.fmtErrorTypeFormat, rt))
}
s.f.causeSec.end(s)
}
}
return
}
func (s *state) writeTrace (err error, addTrace bool) {
if tc := stack.UnwrapTrace(err,true); tc != nil {
s.doTrace = false
s.f.traceSec.begin(s)
for n,f := range tc.Frames() {
s.f.fmeBuilder.BuildFrame(s,f,n)
}
s.f.traceSec.end(s)
}
}
func (s *state) writeField (nfield int) {
}

@ -45,7 +45,7 @@ func (e ErrMulti) Error () string {
return CodeMultiError }
func (e ErrMulti) Unwrap () []error {
func (e ErrMulti) Unwrap() []error {
return e.ErrorList.Clean() }

Loading…
Cancel
Save

Powered by TurnKey Linux.