diff --git a/.golangci.yml b/.golangci.yml index 4d3ce52..e29091d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -112,7 +112,7 @@ linters: - staticcheck - stylecheck # - tagliatelle - - tenv + - usetesting # - testpackage # - thelper - tparallel diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d7b99c..ab5759f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ### Version history +##### 1.2.1 +- Optimization and Refactoring +- Updated documentation + ##### 1.2.0 - Now `-err2-ret-trace` and `err2.SetErrRetTracer` gives us *error return traces* which are even more readable than `-err2-trace`, `err2.SetErrorTracer` with diff --git a/README.md b/README.md index 672b9b7..571e7f3 100644 --- a/README.md +++ b/README.md @@ -623,6 +623,6 @@ Please see the full version history from [CHANGELOG](./CHANGELOG.md). ### Latest Release -##### 1.2.1 -- Optimization and Refactoring +##### 1.2.2 +- Bug Fix (issue-27): automatic error annotation works now for try.T functions - Updated documentation diff --git a/internal/debug/debug.go b/internal/debug/debug.go index f3197d5..2936c17 100644 --- a/internal/debug/debug.go +++ b/internal/debug/debug.go @@ -246,10 +246,25 @@ func fnName(line string) string { j += i } - // remove all anonumous function names (generated by compiler) like - // func1.2, func1, func1.1.1.1, etc. - retval, _, _ := strings.Cut(line[i:j], ".func") - return retval + tryFnNames := []string{".T.", ".T1[...]", ".T2[...]", ".T3[...]"} + line = cleanFuncNames(line[i:j], tryFnNames, true) + + fnNames := []string{".func", "func"} + line = cleanFuncNames(line, fnNames, false) + return line +} + +func cleanFuncNames(line string, names []string, concat bool) string { + for _, name := range names { + b, e, found := strings.Cut(line, name) + if found { + line = b + if concat { + line += e + } + } + } + return line } // fnLNro returns line number in the call stack line. diff --git a/internal/debug/debug_test.go b/internal/debug/debug_test.go index 9850c6e..8923f56 100644 --- a/internal/debug/debug_test.go +++ b/internal/debug/debug_test.go @@ -206,6 +206,36 @@ func TestFnName(t *testing.T) { "github.com/findy-network/findy-agent/agent/ssi.(*DIDAgent).AssertWallet(...)", "ssi.(*DIDAgent).AssertWallet", }, + { + "try.T simple", + "main.TCopyFile.T.func(...)", + "TCopyFile", + }, + { + "try.T simple A", + "main.TCopyFile.T.func3(...)", + "TCopyFile", + }, + { + "try.T1", + "ssi.TCopyFile.T1[...].func3(...)", + "ssi.TCopyFile", + }, + { + "try.T1", + "main.TCopyFile.T1[...].func3(...)", + "TCopyFile", + }, + { + "try.T2 in not main pkg", + "github.com/findy-network/findy-agent/agent/ssi.TCopyFile.T2[...].func3(...)", + "ssi.TCopyFile", + }, + { + "try.T3", + "main.TCopyFile.T3[...].func3(...)", + "TCopyFile", + }, } for _, ttv := range tests { tt := ttv diff --git a/samples/main-play.go b/samples/main-play.go index fabe80f..f8db0ac 100644 --- a/samples/main-play.go +++ b/samples/main-play.go @@ -88,6 +88,23 @@ func TryCopyFile(src, dst string) { try.To1(io.Copy(w, r)) } +func AnnotativeCopyFile(src, dst string) (err error) { + defer err2.Handle(&err) + + r := try.T1(os.Open(src))("failed") + defer r.Close() + + w := try.T1(os.Create(dst))("failed") + defer err2.Handle(&err, func(err error) error { + try.Out(os.Remove(dst)).Logf() + return err + }) + defer w.Close() + + try.T1(io.Copy(w, r))("failed") + return nil +} + func CallRecur(d int) (ret int, err error) { defer err2.Handle(&err) @@ -191,8 +208,10 @@ func doMain() (err error) { } } else { // 2nd argument is empty to assert - TryCopyFile("main.go", "") - //try.To(CopyFile("main.go", "")) + //TryCopyFile("main.go", "") + + // testing try.T function removal from annotation + try.To(AnnotativeCopyFile("main.go", "")) } fmt.Println("=== you cannot see this ===") diff --git a/try/try.go b/try/try.go index c8eaff1..22a844a 100644 --- a/try/try.go +++ b/try/try.go @@ -261,6 +261,10 @@ func IsNotEnabled(err error) bool { // T is similar as [To] but it let's you to annotate a possible error at place. // // try.T(f.Close)("annotations") +// +// Note that T is a helper, which means that you start with it randomly. You +// start with [To] and end up using T if you really need to add context +// related to a specific error check, which is a very rare case. func T(err error) func(fs string) { return func(fs string) { if err == nil { @@ -273,6 +277,10 @@ func T(err error) func(fs string) { // T1 is similar as [To1] but it let's you to annotate a possible error at place. // // f := try.T1(os.Open("filename")("cannot open cfg file") +// +// Note that T1 is a helper, which means that you start with it randomly. You +// start with [To1] and end up using T1 if you really need to add context +// related to a specific error check, which is a very rare case. func T1[T any](v T, err error) func(fs string) T { return func(fs string) T { if err == nil { @@ -283,6 +291,10 @@ func T1[T any](v T, err error) func(fs string) T { } // T2 is similar as [To2] but it let's you to annotate a possible error at place. +// +// Note that T2 is a helper, which means that you start with it randomly. You +// start with [To2] and end up using T2 if you really need to add context +// related to a specific error check, which is a very rare case. func T2[T, U any](v T, u U, err error) func(fs string) (T, U) { return func(fs string) (T, U) { if err == nil { @@ -298,6 +310,10 @@ func annotateErr(err error, fs string) error { } // T3 is similar as [To3] but it let's you to annotate a possible error at place. +// +// Note that T3 is a helper, which means that you start with it randomly. You +// start with [To3] and end up using T3 if you really need to add context +// related to a specific error check, which is a very rare case. func T3[T, U, V any](v1 T, v2 U, v3 V, err error) func(fs string) (T, U, V) { return func(fs string) (T, U, V) { if err == nil { diff --git a/try/try_test.go b/try/try_test.go index 6aaba1e..b648afe 100644 --- a/try/try_test.go +++ b/try/try_test.go @@ -105,15 +105,15 @@ func ExampleIsEOF1() { func Example_copyFile() { copyFile := func(src, dst string) (err error) { - defer err2.Handle(&err, "copy file %s %s", src, dst) + defer err2.Handle(&err, "copy") // These try package helpers are as fast as Check() calls which is as // fast as `if err != nil {}` - r := try.To1(os.Open(src)) + r := try.T1(os.Open(src))("source file") defer r.Close() - w := try.To1(os.Create(dst)) + w := try.T1(os.Create(dst))("target file") defer err2.Handle(&err, err2.Err(func(error) { os.Remove(dst) })) @@ -126,5 +126,5 @@ func Example_copyFile() { if err != nil { fmt.Println(err) } - // Output: copy file /notfound/path/file.go /notfound/path/file.bak: open /notfound/path/file.go: no such file or directory + // Output: copy: source file: open /notfound/path/file.go: no such file or directory }