// ------------------------------------------------------------------------ // Project active2 // Active Thing (activething.com) git.activething.com/go // // File Name active.go // Created by DEV // Modified 20/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 erdata import ( "reflect" "sync" "time" ) const ( FieldNameError string = "error" FieldNameCode string = "code" FieldNameType string = "type" FieldNameTypes string = "types" FieldNameFields string = "fields" FieldNameCause string = "cause" FieldNameCauses string = "causes" FieldNameTrace string = "trace" ) const( fieldNameMessage string = "message" fieldNameInfo string = "info" fieldNameDate string = "date" fieldNameTime string = "time" fieldNameParam string = "param" fieldNameSource string = "source" fieldNameUser string = "user" ) const ( fmtNameDuplicated string = "%s-%d" ) var ( g = struct { mux sync.RWMutex typeCollectors map[reflect.Type]ErrorCollector defaultCollectors FieldCollectors }{ typeCollectors : make(map[reflect.Type]ErrorCollector), defaultCollectors: defaultCollectors(), } ) func getTypeCollector (rtype reflect.Type) ErrorCollector { ec,_ := g.typeCollectors[rtype] return ec } func CollectErrorFields (collector Collector, err error) { if err == nil { return } rt := reflect.TypeOf(err) if rt.Kind() == reflect.Pointer { rt = rt.Elem() } if ec,is := err.(Collectable); is { ec.Collect(collector) return } g.mux.RLock() eb,_ := g.typeCollectors[rt] g.mux.RUnlock() if eb != nil { eb.CollectError(collector,err) return } var nc FieldCollectors for _,f := range g.defaultCollectors { if f.CollectField(collector,err) { nc = append(nc, f) } } g.mux.Lock() g.typeCollectors[rt]=nc g.mux.Unlock() } func defaultCollectors () FieldCollectors { return []FieldCollector{ CollectFieldFnc(func (b Collector, e error ) bool { if ms,is := e.(interface { Message() string }); is { b.AddFieldString(fieldNameMessage, ms.Message()) return true } return false }), CollectFieldFnc(func (b Collector, e error ) bool { if in,is := e.(interface { Info () string }); is { b.AddFieldString(fieldNameInfo,in.Info()) return true } return false }), CollectFieldFnc(func (b Collector, e error ) bool { if tm,is := e.(interface { Time() time.Time }); is { b.AddFieldTime(fieldNameTime, tm.Time()) return true } return false }), CollectFieldFnc(func (b Collector, e error ) bool { if tm,is := e.(interface { Date() time.Time }); is { b.AddFieldDate(fieldNameDate, tm.Date()) return true } return false }), CollectFieldFnc(func (b Collector, e error ) bool { if tm,is := e.(interface { Param() string }); is { b.AddFieldString(fieldNameParam, tm.Param()) return true } return false }), CollectFieldFnc(func (b Collector, e error ) bool { if tm,is := e.(interface { User() string }); is { b.AddFieldString(fieldNameUser, tm.User()) return true } return false }), CollectFieldFnc(func (b Collector, e error ) bool { if tm,is := e.(interface { Source() string }); is { b.AddFieldString(fieldNameSource, tm.Source()) return true } return false }), } }