Skip to content

Commit

Permalink
feat: errors/errorsutil: add ErrorWithLocation{}, `NewErrorWithLo…
Browse files Browse the repository at this point in the history
…cation()`
  • Loading branch information
grokify committed Dec 27, 2024
1 parent 329b541 commit 8aab37c
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
32 changes: 32 additions & 0 deletions errors/errorsutil/error_with_location.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package errorsutil

import (
"fmt"
"runtime"
)

// ErrorWithLocation represents an error message with code file and line locaiton.
// It is automatically populated when instantiated with `NewErrorWithLocation()`,
// and follows the `errors.Error` interface.
type ErrorWithLocation struct {
Msg string
File string
Line int
}

func (e *ErrorWithLocation) Error() string {
return fmt.Sprintf("%s (at %s:%d)", e.Msg, e.File, e.Line)
}

func NewErrorWithLocation(msg string) error {
_, file, line, ok := runtime.Caller(1)
if !ok {
file = "unknown"
line = -1
}
return &ErrorWithLocation{
Msg: msg,
File: file,
Line: line,
}
}
34 changes: 34 additions & 0 deletions errors/errorsutil/error_with_location_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package errorsutil

import (
"strings"
"testing"
"time"
)

var errorWithLocationTests = []struct {
fn func() error
errMsgSuffix string
}{
{func() error { _, err := time.Parse(time.RFC3339, "Mon, 2024-12-31"); return err }, "github.com/grokify/mogo/errors/errorsutil/error_with_location_test.go:22"},
}

func TestErrorWithLocation(t *testing.T) {
for _, tt := range errorWithLocationTests {
try := tt.fn()
if try == nil {
panic("no error")
}
tryWithLocation := NewErrorWithLocation(try.Error())
idx, idxCalc, ok := isSuffixOnly(tryWithLocation.Error(), tt.errMsgSuffix)
if !ok {
t.Errorf("errorsutil.NewErrorWithLocation(\"%s\"): mismatch want suffix (%s) got (%s), idx (%d) idxCalc (%d)", tryWithLocation.Error(), tt.errMsgSuffix, tryWithLocation.Error(), idx, idxCalc)
}
}
}

func isSuffixOnly(s, substr string) (int, int, bool) {
idx := strings.Index(s, substr)
idxCalc := len(s) - len(substr) - 1
return idx, idxCalc, idx == idxCalc
}

0 comments on commit 8aab37c

Please sign in to comment.