zerr: sequence: changed into interface for future proofing
This commit is contained in:
parent
dba226c1c1
commit
ab159d9426
|
@ -27,7 +27,7 @@ type Err struct {
|
||||||
id string
|
id string
|
||||||
logger Logger
|
logger Logger
|
||||||
notifier Notifier
|
notifier Notifier
|
||||||
sequence *Sequence
|
sequence Sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join implements Error.
|
// Join implements Error.
|
||||||
|
@ -215,7 +215,7 @@ func (mu *Err) Notify(ctx context.Context, opts ...zoptions.NotifyOption) Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sequence returns the state of the error sequence.
|
// Sequence returns the state of the error sequence.
|
||||||
func (mu *Err) Sequence() *Sequence {
|
func (mu *Err) Sequence() Sequence {
|
||||||
return mu.sequence
|
return mu.sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,10 @@ func (er *Err) WriteBuilder(w io.Writer) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var previous string
|
var previous string
|
||||||
if err := er.sequence.Outer(); err != nil && !err.IsMulti() {
|
if parent := er.sequence.Parent(); parent != nil {
|
||||||
previous = err.GetMessage()
|
if err := parent.Error(); err != nil && !err.IsMulti() {
|
||||||
|
previous = err.GetMessage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
current := strings.TrimPrefix(er.message, previous)
|
current := strings.TrimPrefix(er.message, previous)
|
||||||
if current != "" {
|
if current != "" {
|
||||||
|
|
|
@ -85,7 +85,9 @@ type Error interface {
|
||||||
Notify(ctx context.Context, opts ...zoptions.NotifyOption) Error
|
Notify(ctx context.Context, opts ...zoptions.NotifyOption) Error
|
||||||
|
|
||||||
// Sequence returns the state of the error sequence.
|
// Sequence returns the state of the error sequence.
|
||||||
Sequence() *Sequence
|
//
|
||||||
|
// Sequence must not be nil.
|
||||||
|
Sequence() Sequence
|
||||||
|
|
||||||
// IsMulti returns true if the error is a multiple error.
|
// IsMulti returns true if the error is a multiple error.
|
||||||
IsMulti() bool
|
IsMulti() bool
|
||||||
|
|
|
@ -9,24 +9,50 @@ import "iter"
|
||||||
// When wrapping errors, the wrapping error
|
// When wrapping errors, the wrapping error
|
||||||
// will be the parent of the wrapped Error
|
// will be the parent of the wrapped Error
|
||||||
// if the wrapped Error is a zerr.Error.
|
// if the wrapped Error is a zerr.Error.
|
||||||
type Sequence struct {
|
type Sequence interface {
|
||||||
parent *Sequence
|
// WrapBy prepends the next Sequence to the current Sequence.
|
||||||
children []*Sequence
|
WrapBy(parent Sequence)
|
||||||
|
|
||||||
|
// Parent returns the parent Sequence.
|
||||||
|
// Return nil if this Sequence is Root.
|
||||||
|
Parent() Sequence
|
||||||
|
|
||||||
|
// Root returns the outermost Sequence in the sequence.
|
||||||
|
//
|
||||||
|
// Returns self if current Sequence is the outermost.
|
||||||
|
Root() Sequence
|
||||||
|
|
||||||
|
// IsRoot checks if the Sequence is the outermost Sequence in the sequence.
|
||||||
|
IsRoot() bool
|
||||||
|
|
||||||
|
// Error returns the Error in the sequence.
|
||||||
|
Error() Error
|
||||||
|
|
||||||
|
// Iter returns an iterator to traverse Errors in the sequence.
|
||||||
|
Iter() iter.Seq[Error]
|
||||||
|
|
||||||
|
// AppendChild appends a child Sequence to the current Sequence.
|
||||||
|
AppendChild(child Sequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
type sequence struct {
|
||||||
|
parent Sequence
|
||||||
|
children []Sequence
|
||||||
err Error
|
err Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// WrapBy prepends the next Sequence to the current Sequence.
|
func (se *sequence) WrapBy(parent Sequence) {
|
||||||
func (se *Sequence) WrapBy(parent *Sequence) {
|
parent.AppendChild(se)
|
||||||
parent.children = append(parent.children, se)
|
|
||||||
se.parent = parent
|
se.parent = parent
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outer returns the error that wraps this Error.
|
func (se *sequence) AppendChild(child Sequence) {
|
||||||
// Return nil if this Error is not wrapped
|
se.children = append(se.children, child)
|
||||||
// or wrapping outer is not a zerr.Error.
|
}
|
||||||
func (se *Sequence) Outer() Error {
|
|
||||||
|
func (se *sequence) Parent() Sequence {
|
||||||
if se.parent != nil {
|
if se.parent != nil {
|
||||||
return se.parent.err
|
return se.parent
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -34,21 +60,23 @@ func (se *Sequence) Outer() Error {
|
||||||
// Root returns the outermost Error in the sequence.
|
// Root returns the outermost Error in the sequence.
|
||||||
//
|
//
|
||||||
// Returns self if there is no outermost.
|
// Returns self if there is no outermost.
|
||||||
func (se *Sequence) Root() *Sequence {
|
func (se *sequence) Root() Sequence {
|
||||||
root := se
|
var root Sequence = se
|
||||||
for root.parent != nil {
|
for {
|
||||||
root = root.parent
|
if root.Parent() == nil {
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
root = root.Parent()
|
||||||
}
|
}
|
||||||
return root
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsRoot checks if the Error is the outermost Error in the sequence.
|
// IsRoot checks if the Error is the outermost Error in the sequence.
|
||||||
func (se *Sequence) IsRoot() bool {
|
func (se *sequence) IsRoot() bool {
|
||||||
return se.parent == nil
|
return se.parent == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error returns the Error in the sequence.
|
// Error returns the Error in the sequence.
|
||||||
func (se *Sequence) Error() Error {
|
func (se *sequence) Error() Error {
|
||||||
return se.err
|
return se.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +92,7 @@ func (se *Sequence) Error() Error {
|
||||||
// // e is zerr.Error
|
// // e is zerr.Error
|
||||||
// // do something with e
|
// // do something with e
|
||||||
// }
|
// }
|
||||||
func (se *Sequence) Iter() iter.Seq[Error] {
|
func (se *sequence) Iter() iter.Seq[Error] {
|
||||||
return func(yield func(Error) bool) {
|
return func(yield func(Error) bool) {
|
||||||
if se.err != nil && !yield(se.err) {
|
if se.err != nil && !yield(se.err) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -7,19 +7,20 @@ import (
|
||||||
"gitlab.bareksa.com/backend/zen/core/zoptions"
|
"gitlab.bareksa.com/backend/zen/core/zoptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WrapInitialInput struct {
|
type WrapInput struct {
|
||||||
Error error
|
Errors []error
|
||||||
Message string
|
Message string
|
||||||
PC uintptr
|
PC uintptr
|
||||||
Time time.Time
|
Time time.Time
|
||||||
Logger Logger
|
Logger Logger
|
||||||
Notifier Notifier
|
Notifier Notifier
|
||||||
|
Details []any
|
||||||
}
|
}
|
||||||
|
|
||||||
type Wrapper interface {
|
type Wrapper interface {
|
||||||
// Wrap creates a zerr.Error with inputs
|
// Wrap creates a zerr.Error with inputs
|
||||||
// generated by global entry points.
|
// generated by global entry points.
|
||||||
Wrap(input WrapInitialInput) Error
|
Wrap(input WrapInput) Error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
|
@ -30,12 +31,35 @@ type Notifier interface {
|
||||||
NotifyError(ctx context.Context, err Error, opts ...zoptions.NotifyOption)
|
NotifyError(ctx context.Context, err Error, opts ...zoptions.NotifyOption)
|
||||||
}
|
}
|
||||||
|
|
||||||
type WrapperFunc func(input WrapInitialInput) Error
|
type WrapperFunc func(input WrapInput) Error
|
||||||
|
|
||||||
func (wr WrapperFunc) Wrap(input WrapInitialInput) Error {
|
func (wr WrapperFunc) Wrap(input WrapInput) Error {
|
||||||
return wr(input)
|
return wr(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultWrapper Wrapper = WrapperFunc(func(input WrapInitialInput) Error {
|
var DefaultWrapper Wrapper = WrapperFunc(func(input WrapInput) Error {
|
||||||
panic("not implemented")
|
e := &Err{
|
||||||
|
message: input.Message,
|
||||||
|
errs: input.Errors,
|
||||||
|
caller: input.PC,
|
||||||
|
time: input.Time,
|
||||||
|
logger: input.Logger,
|
||||||
|
notifier: input.Notifier,
|
||||||
|
details: input.Details,
|
||||||
|
}
|
||||||
|
e.sequence = &sequence{err: e}
|
||||||
|
for _, err := range input.Errors {
|
||||||
|
if err, ok := err.(Error); ok {
|
||||||
|
err.Sequence().WrapBy(e.sequence)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e
|
||||||
})
|
})
|
||||||
|
|
||||||
|
func Wrap(input WrapInput) Error {
|
||||||
|
return DefaultWrapper.Wrap(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDefaultWrapper(w Wrapper) {
|
||||||
|
DefaultWrapper = w
|
||||||
|
}
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -6,6 +6,8 @@ require (
|
||||||
connectrpc.com/connect v1.16.2
|
connectrpc.com/connect v1.16.2
|
||||||
connectrpc.com/grpcreflect v1.2.0
|
connectrpc.com/grpcreflect v1.2.0
|
||||||
github.com/fatih/color v1.17.0
|
github.com/fatih/color v1.17.0
|
||||||
|
github.com/mattn/go-isatty v0.0.20
|
||||||
|
github.com/pborman/indent v1.2.1
|
||||||
github.com/tidwall/pretty v1.2.1
|
github.com/tidwall/pretty v1.2.1
|
||||||
golang.org/x/net v0.23.0
|
golang.org/x/net v0.23.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
|
@ -13,8 +15,6 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
|
||||||
github.com/pborman/indent v1.2.1 // indirect
|
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
golang.org/x/sys v0.18.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue