From f20b4a6359f3a73495f5d4a53a21d8c5d0082a47 Mon Sep 17 00:00:00 2001 From: Tigor Hutasuhut Date: Fri, 23 Aug 2024 18:41:19 +0700 Subject: [PATCH] zerr: update implementation --- core/zerr/{implementation.go => err.go} | 7 +++ core/zerr/err_write_to.go | 74 +++++++++++++++++++++++++ core/zerr/error.go | 7 +++ go.mod | 1 + go.sum | 2 + 5 files changed, 91 insertions(+) rename core/zerr/{implementation.go => err.go} (97%) create mode 100644 core/zerr/err_write_to.go diff --git a/core/zerr/implementation.go b/core/zerr/err.go similarity index 97% rename from core/zerr/implementation.go rename to core/zerr/err.go index adad7fb..ab065cc 100644 --- a/core/zerr/implementation.go +++ b/core/zerr/err.go @@ -12,6 +12,8 @@ import ( "gitlab.bareksa.com/backend/zen/core/zoptions" ) +var _ Error = (*Err)(nil) + type Err struct { message string publicMessage string @@ -210,3 +212,8 @@ func (mu *Err) Sequence() *Sequence { func (mu *Err) Unwrap() []error { return mu.errs } + +// IsMulti implements Error. +func (mu *Err) IsMulti() bool { + return len(mu.errs) > 1 +} diff --git a/core/zerr/err_write_to.go b/core/zerr/err_write_to.go new file mode 100644 index 0000000..01c98d4 --- /dev/null +++ b/core/zerr/err_write_to.go @@ -0,0 +1,74 @@ +package zerr + +import ( + "io" + "strconv" + "strings" + + "github.com/pborman/indent" +) + +// WriteBuilder writes the error to the builder. +// +// w is guaranteed to never return error because +// the underlying most writer is a strings.Builder. +func (er *Err) WriteBuilder(w io.Writer) { + if len(er.errs) == 0 { + _, _ = io.WriteString(w, "[nil]") + return + } + var previous string + if err := er.sequence.Outer(); err != nil && !err.IsMulti() { + previous = err.GetMessage() + } + current, _ := strings.CutPrefix(er.message, previous) + if current != "" { + if previous != "" { + _, _ = io.WriteString(w, ": ") + } + _, _ = io.WriteString(w, current) + } + + if len(er.errs) == 1 { + err := er.errs[0] + if wb, ok := err.(interface{ WriteBuilder(io.Writer) }); ok { + wb.WriteBuilder(w) + return + } + _, _ = io.WriteString(w, ": ") + _, _ = io.WriteString(w, err.Error()) + return + } + + _, _ = io.WriteString(w, ":\n") + w = indent.NewWriter(w, " ") + + for i, e := range er.errs { + if i > 0 { + _, _ = io.WriteString(w, "\n") + } + _, _ = io.WriteString(w, strconv.Itoa(i+1)) + _, _ = io.WriteString(w, ". ") + if wb, ok := e.(interface{ WriteBuilder(io.Writer) }); ok { + wb.WriteBuilder(w) + continue + } + _, _ = io.WriteString(w, e.Error()) + _, _ = io.WriteString(w, "\n") + } +} + +func writeString(w io.Writer, s string) (n int64, err error) { + n64, err := io.WriteString(w, s) + return int64(n64), err +} + +func writeByte(w io.Writer, b byte) (n int64, err error) { + n64, err := w.Write([]byte{b}) + return int64(n64), err +} + +func writeBytes(w io.Writer, b []byte) (n int64, err error) { + n64, err := w.Write(b) + return int64(n64), err +} diff --git a/core/zerr/error.go b/core/zerr/error.go index fd086a9..513f480 100644 --- a/core/zerr/error.go +++ b/core/zerr/error.go @@ -61,4 +61,11 @@ type Error interface { // Sequence returns the state of the error sequence. Sequence() *Sequence + + // IsMulti returns true if the error is a multiple error. + IsMulti() bool + + // Resolve returns error (self) if all the errors + // are valid. + Resolve() error } diff --git a/go.mod b/go.mod index 45f5bd9..7b11616 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( require ( 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/text v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 3ab36a1..6eb5659 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pborman/indent v1.2.1 h1:lFiviAbISHv3Rf0jcuh489bi06hj98JsVMtIDZQb9yM= +github.com/pborman/indent v1.2.1/go.mod h1:FitS+t35kIYtB5xWTZAPhnmrxcciEEOdbyrrpz5K6Vw= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=