Error handling - pkg/errors - Cause() should be RootCause()?!


(Arjun Dhar) #1

Hi,

Just started getting used the errors package.
Also, ive read blogs and am aware of %+v option, however am looking to iterate the trace myself and not have it just printed.

Lets dive into the code first and I’ll talk about issues am facing.

e = errors.New("[Area] multiplier wasnt a positive int")

		e = errors.Wrap(e, "[main] Area failed for -1")
		e = errors.Wrap(e, "Top most error")

		fmt.Printf("\nErr=%s", fmt.Errorf("%+v", e)) //Raw Print : Cool !
		
		for tabs:=0; ; tabs++ {	//Id have preferred e!=nil but e will never be nil since Cause always retunrs root cause		
			fmt.Printf("\n%s+-- %s", strings.Repeat("    ", tabs), errors.Errorf("%v", e))
			if _e:=errors.Cause(e); _e==e {  // Cause of an error @ leaf is Error ??!! ummmm ok!
				 break; 
			} else {
				e = _e
			}
		}

Output:

Err=Top most error: [main] Area failed for -1: [Area] multiplier wasnt a positive int
+-- Top most error: [main] Area failed for -1: [Area] multiplier wasnt a positive int
. +-- [Area] multiplier wasnt a positive int

Questions

  1. When I get the error , top of the stack I just want the message for that level. Not all its nested ones included. How do i do that?
  2. Cause() is actually behaving as RootCause() ; how do I get an immediate nested cause for an error?
  3. I looked around and seems this is the standard one that people use. Am open to any library that handle the cases OOB, if im not missing anything above.

(Jakob Borg) #2

This is indeed how pkg/errors works – Cause() gives you the “first” or “most-wrapped” error, RootCause() if you like. This is typically the thing that is interesting to compare against io.EOF or whatnot.

There might be packages to construct trees of errors and inspect all the layers, but this seems like caring a little too much about the inner details of the error…


(Arjun Dhar) #3

Thanks. I understand, its a bit surprising that something like error handling has not been quite well addressed by the standard lib.

For what its worth I’d like to see the following make it s way to standard lib:

  • Improved nomenclature to avoid misunderstandings like these
  • Clear distinction between Cause and RootCause since RootCause in the form of Cause currently has a wide usage base.
  • Any library should be able to provide a source of truth to the data and how one views it is programmatic choice. Providing a default implementation to view in say %+v easy reduced verbosity (awesome) is great but I hope the standard lib will address this short coming (as I view it).

I wont state matured examples from other languages to start any trolling but I think experienced Go developers can comment on what they feel about it.

Disagree @ caring a little too much about the inner details of the error - Because go’s error handling style is to bubble it up via the code. The top most of this stack should have all the means to deal with it without using any form of string introspection. (Which is why the pkg/errors Wrap became useful to begin with). You dont wanna Wrap something that cant be Unwrapped.
(Apologize if I misunderstood that statement :slight_smile: )

…without quoting anyone; through a different channel the grapevine has it pkg/errors maybe deprecated.