From 19c2f5a65d20050c7a50911c6484306cccafa244 Mon Sep 17 00:00:00 2001 From: Harri Lainio Date: Thu, 16 Oct 2025 17:47:27 +0300 Subject: [PATCH 1/4] add sample to test issue #30, Handle in function name in app pkg --- samples/main-overlap.go | 25 +++++++++++++++++++++++++ samples/main.go | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 samples/main-overlap.go diff --git a/samples/main-overlap.go b/samples/main-overlap.go new file mode 100644 index 0000000..dced6fb --- /dev/null +++ b/samples/main-overlap.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + + "github.com/lainio/err2" + "github.com/lainio/err2/try" +) + +func doOverlapMain() { + err := FirstHandle() + fmt.Printf("Final error: %v\n", err) +} + +func FirstHandle() (err error) { + defer err2.Handle(&err) + try.To(SecondHandle()) + return nil +} + +func SecondHandle() (err error) { + defer err2.Handle(&err) + try.To(fmt.Errorf("my error")) + return nil +} diff --git a/samples/main.go b/samples/main.go index 9d901e9..8bc5eba 100644 --- a/samples/main.go +++ b/samples/main.go @@ -41,6 +41,8 @@ func main() { } switch *mode { + case "overlap": + doOverlapMain() case "db": doDBMain() case "nil": From acd5122961304a6baa8c054608ee6f6bc591a6df Mon Sep 17 00:00:00 2001 From: Harri Lainio Date: Thu, 16 Oct 2025 18:03:20 +0300 Subject: [PATCH 2/4] fixing bug in automatic error annotation: FuncName search must be inside err2 pkg --- internal/debug/debug.go | 5 ++++ internal/debug/debug_test.go | 51 +++++++++++++++++++++++++++----- internal/handler/handler.go | 2 +- internal/handler/handler_test.go | 2 +- 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/internal/debug/debug.go b/internal/debug/debug.go index 2936c17..905a2b3 100644 --- a/internal/debug/debug.go +++ b/internal/debug/debug.go @@ -56,6 +56,11 @@ var ( } ) +// Err2PackageID is the name ID of err2. When its API will update, e.g., v2, the +// ID must be updated as following "lainio/err2/v2", etc. See tests for +// isFuncAnchor. +const Err2PackageID = "lainio/err2" + func (si StackInfo) fullName() string { dot := "" if si.PackageName != "" && si.FuncName != "" { diff --git a/internal/debug/debug_test.go b/internal/debug/debug_test.go index 8923f56..552a327 100644 --- a/internal/debug/debug_test.go +++ b/internal/debug/debug_test.go @@ -119,28 +119,65 @@ func TestIsFuncAnchor(t *testing.T) { StackInfo{"", "", 0, PackageRegexp, nil, false}}, true}, {"short", args{ "github.com/lainio/err2.printStackIf({0x1545d2, 0x6}, 0x0, {0x12e3e0?, 0x188f50?})", - StackInfo{"", "", 0, nil, nil, false}}, true}, + StackInfo{Err2PackageID, "", 0, nil, nil, false}}, true}, {"short-but-false", args{ "github.com/lainio/err2.printStackIf({0x1545d2, 0x6}, 0x0, {0x12e3e0?, 0x188f50?})", - StackInfo{"err2", "Handle", 0, nil, nil, false}}, false}, + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, false}, {"medium", args{ "github.com/lainio/err2.Returnw(0x40000b3e60, {0x0, 0x0}, {0x0, 0x0, 0x0})", - StackInfo{"err2", "Returnw", 0, nil, nil, false}}, true}, + StackInfo{Err2PackageID, "Returnw", 0, nil, nil, false}}, true}, {"medium-but-false", args{ "github.com/lainio/err2.Returnw(0x40000b3e60, {0x0, 0x0}, {0x0, 0x0, 0x0})", - StackInfo{"err2", "Return(", 0, nil, nil, false}}, false}, + StackInfo{Err2PackageID, "Return(", 0, nil, nil, false}}, false}, {"long", args{ "github.com/lainio/err2.Handle(0x40000b3ed8, 0x40000b3ef8)", - StackInfo{"err2", "Handle", 0, nil, nil, false}}, true}, + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, true}, {"package name only", args{ "github.com/lainio/err2/try.To1[...](...)", - StackInfo{"lainio/err2", "", 0, nil, nil, false}}, true}, + StackInfo{Err2PackageID, "", 0, nil, nil, false}}, true}, + + // From bug (issue #30 and PR #31) tests, Handle name in own pkg + {"user pkg containing Handle should not match", args{ + "mainHandle.First(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, false}, + {"user function containing Handle should not match", args{ + "main.FirstHandle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, false}, + {"user function containing Handle matches err2.Handle", args{ + "github.com/lainio/err2.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, true}, + {"user function named exactly Handle should not match", args{ + "main.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, false}, + {"user package function named Handle should not match", args{ + "mypackage.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{"err2", "Handle", 0, nil, nil, false}}, false}, + {"err2.Handle should match", args{ + "err2.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{"err2", "Handle", 0, nil, nil, false}}, true}, + {"lainio/err2.Handle should match", args{ + "github.com/lainio/err2.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, true}, + {"user package with err2 in path should not match", args{ + "github.com/mycompany/err2/mypackage.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, false}, + {"non-err2 versioned package should not match", args{ + "github.com/someone/otherpkg/v2.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID, "Handle", 0, nil, nil, false}}, false}, + + // See the PackageID!! + {"versioned err2/v2.Handle should match", args{ + "github.com/lainio/err2/v2.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID + "/v2", "Handle", 0, nil, nil, false}}, true}, + {"versioned err2/v10.Handle should match", args{ + "github.com/lainio/err2/v10.Handle(0x40000b3ed8, 0x40000b3ef8)", + StackInfo{Err2PackageID + "/v10", "Handle", 0, nil, nil, false}}, true}, } for _, ttv := range tests { tt := ttv t.Run(tt.name, func(t *testing.T) { t.Parallel() - expect.Equal(t, tt.retval, tt.isFuncAnchor(tt.input)) + expect.Equal(t, tt.isFuncAnchor(tt.input), tt.retval) }) } } diff --git a/internal/handler/handler.go b/internal/handler/handler.go index 98e3831..207e4d9 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -349,7 +349,7 @@ func doBuildFormatStr(info *Info, lvl int) (fs string, ok bool) { fnName = info.CallerName } funcName, _, _, ok := debug.FuncName(debug.StackInfo{ - PackageName: "", + PackageName: debug.Err2PackageID, // limit fn name search to err2 pkg FuncName: fnName, Level: lvl, }) diff --git a/internal/handler/handler_test.go b/internal/handler/handler_test.go index 1755a0d..0aae249 100644 --- a/internal/handler/handler_test.go +++ b/internal/handler/handler_test.go @@ -157,7 +157,7 @@ func TestPreProcess_debug(t *testing.T) { expect.ThatNot(t, nilHandlerCalled) // See the name of this test function. Decamel it + error - const want = "testing: t runner: error" + const want = "error" expect.Equal(t, myErrVal.Error(), want) resetCalled() From 238d2f9d4df30e99414e0749bce1ef9cdf10b60e Mon Sep 17 00:00:00 2001 From: Harri Lainio Date: Wed, 5 Nov 2025 16:03:13 +0200 Subject: [PATCH 3/4] usage for overlap mode --- samples/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/main.go b/samples/main.go index 8bc5eba..f7d8806 100644 --- a/samples/main.go +++ b/samples/main.go @@ -16,6 +16,7 @@ var ( "play", "runs the wanted playground: db, play, nil, assert,"+ "\nassert-keep (= uses assert.Debug in GLS),"+ + "\noverlap (= our fn names can be like MyHandle, myCatch, ..),"+ "\nplay-recursion (= runs recursion example)", ) isErr = flag.Bool("err", false, "tells if we want to have an error") From aa656e4caa75ca3c74719ec3aa790ac0f7bb358c Mon Sep 17 00:00:00 2001 From: Harri Lainio Date: Wed, 5 Nov 2025 16:22:04 +0200 Subject: [PATCH 4/4] rename helper filenames & overlap mode uses call annoation --- samples/{main-db-sample.go => db-sample.go} | 0 samples/{main-nil.go => nil.go} | 0 samples/{main-overlap.go => overlap.go} | 2 +- samples/{main-play.go => play.go} | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename samples/{main-db-sample.go => db-sample.go} (100%) rename samples/{main-nil.go => nil.go} (100%) rename samples/{main-overlap.go => overlap.go} (85%) rename samples/{main-play.go => play.go} (100%) diff --git a/samples/main-db-sample.go b/samples/db-sample.go similarity index 100% rename from samples/main-db-sample.go rename to samples/db-sample.go diff --git a/samples/main-nil.go b/samples/nil.go similarity index 100% rename from samples/main-nil.go rename to samples/nil.go diff --git a/samples/main-overlap.go b/samples/overlap.go similarity index 85% rename from samples/main-overlap.go rename to samples/overlap.go index dced6fb..f276fb6 100644 --- a/samples/main-overlap.go +++ b/samples/overlap.go @@ -20,6 +20,6 @@ func FirstHandle() (err error) { func SecondHandle() (err error) { defer err2.Handle(&err) - try.To(fmt.Errorf("my error")) + try.T(fmt.Errorf("my error"))("my call lvl annotation") return nil } diff --git a/samples/main-play.go b/samples/play.go similarity index 100% rename from samples/main-play.go rename to samples/play.go