consider counting and listing instances of uniform error handling within a func
thepudds opened this issue · comments
As far as I understand, this first-cut version of tryhard
currently undercounts possible uses of try
because tryhard
does not look for cases of uniform error handling within a function.
Consider reporting at least certain classes of uniform error handling within a function.
These would be candidates for try
+ defer
. Actually re-writing to use defer
could be left as an exercise for the reader.
For example, it would be nice to identify f()
and g()
below as each having two candidate locations for try
:
// f uses a function literal to annotate errors uniformly
func f(arg int) error {
report := func(err error) error { return fmt.Errorf("f failed for %v: %v", arg, err) }
err := g(arg)
if err != nil {
return report(err)
}
err = h(arg)
if err != nil {
return report(err)
}
return nil
}
// g uses repeated code (e.g., copy/paste) to annotate errors uniformly
func g(arg int) error {
err := h(arg)
if err != nil {
return fmt.Errorf("g failed for %v: %v", arg, err)
}
err = f(arg)
if err != nil {
return fmt.Errorf("g failed with %v: %v", arg, err)
}
return nil
}
func h(arg int) error {
return nil
}
This is a variation (I think?) of the suggestions in golang/go#32437 (comment).
I encountered this as well while tryhard'ing my own code; see golang/go#32437 (comment).
@thepudds Just FYI, in your example above, g
has different error returns - the format string is not the same in both cases.
Anyway, I just uploaded a new version of tryhard
that recognizes these cases. Note that there is a significant change of false positives for that new count. If a function has shared error returns they will be reported but if there are other error returns that don't fit the try
pattern, using a defer
may not be straight-forward.
Closing. try
proposal was abandoned.