diff --git a/yaerrors/yaerrors.go b/yaerrors/yaerrors.go index 3bee721..f23fd66 100644 --- a/yaerrors/yaerrors.go +++ b/yaerrors/yaerrors.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net/http" + "strings" "github.com/YaCodeDev/GoYaCodeDevUtils/yalogger" ) @@ -22,8 +23,14 @@ type Error interface { Code() int Error() string Unwrap() error + UnwrapLastError() string } +const ( + codeSeparate = " | " + errorSeparate = " -> " +) + // Minimal error implementation for Error interface. type yaError struct { code int @@ -82,7 +89,7 @@ func FromStringWithLog(code int, msg string, log yalogger.Logger) Error { func (e *yaError) Error() string { safetyCheck(&e) - return fmt.Sprintf("%d | %s", e.code, e.traceback) + return fmt.Sprintf("%d%s%s", e.code, codeSeparate, e.traceback) } // Returns the original error that caused this error. @@ -92,12 +99,26 @@ func (e *yaError) Unwrap() error { return e.cause } +// Returns the last error. +func (e *yaError) UnwrapLastError() string { + safetyCheck(&e) + + traceback := []byte(e.traceback) + + end := strings.Index(e.traceback, errorSeparate) + if end == -1 { + return e.traceback + } + + return string(traceback[:end]) +} + // Wrap adds a message to the error traceback, providing additional context. // It is highly recommended to use this method each time you return the error // to a higher level in the call stack. func (e *yaError) Wrap(msg string) Error { safetyCheck(&e) - e.traceback = fmt.Sprintf("%s -> %s", msg, e.traceback) + e.traceback = fmt.Sprintf("%s%s%s", msg, errorSeparate, e.traceback) return e } diff --git a/yaerrors/yaerrors_test.go b/yaerrors/yaerrors_test.go index e3edcdc..0fd3a58 100644 --- a/yaerrors/yaerrors_test.go +++ b/yaerrors/yaerrors_test.go @@ -1,6 +1,8 @@ package yaerrors_test import ( + "errors" + "fmt" "testing" "github.com/YaCodeDev/GoYaCodeDevUtils/yaerrors" @@ -62,3 +64,24 @@ func TestYaError_Wrap(t *testing.T) { ) } } + +func TestYaErrorUnwrap_Works(t *testing.T) { + err := yaerrors.FromError(404, yaerrors.ErrTeapot, "Not Found") + if !errors.Is(err.Unwrap(), yaerrors.ErrTeapot) { + t.Fatalf( + fmt.Sprintf("Error didn't unwrap as %v", yaerrors.ErrTeapot), + err.Error(), + ) + } +} + +func TestYaErrorUnwrapLastError_Works(t *testing.T) { + expected := "Wrapped error" + + err := yaerrors.FromError(404, yaerrors.ErrTeapot, "Not Found").Wrap(expected) + got := err.UnwrapLastError() + + if got != expected { + t.Fatalf("Error didn't unwrap correctly:\n got: %v\n want: %v", got, expected) + } +}