Skip to content

Expose traceTree or some variant #71

Description

@bufdev

This was motivated by wanting to get a printout of just the stack trace, without the underlying error message. That use was was a situation where I had error interceptor logic in place, but didn't control the underlying location where the error was printed, as that was controlled by a different library (github.com/spf13/cobra). I just wanted to get a stack trace to print out to a debug logger, but realized I couldn't just yet.

This could take different forms:

  • Just expose traceTree directly. Likely not great, you probably don't want users mucking with this.
  • Have some public partial type that maps to traceTree under the hood.
  • Don't expose traceTree fully, but expose FormatTrace/FormatTraceString or the like that just drops the error itself (would solve my original issue, but isn't as universal).

Potentially the most idiomatic way to do this would be to expose some custom error type where I can use errors.Is/As, which would solve the problem more generally, but I assume this was ruled out.

I may be missing something here, just starting to muck around with the library - apologies if this is polluting the issue space!

Activity

  1. abhinav commented on Dec 9, 2023

    @abhinav
    Contributor

    Hey, @bufdev!

    I think exporting traceTree is okay: it doesn't have any internal details—not even the program counters. It's just a plain data structure. (Thinking out loud, probably: func Inspect(error) *Tree.)

    Although I agree—exporting this is not my favorite solution. However, it seems better than an overly complicated error tree walker, which is the other option we were considering here to optimize on allocs during formatting. We might still do that in the future, but it could be an internal detail for formatting and the public Inspect function can remain.

    @prashantv Do you have thoughts on this?

  2. bufdev commented on Dec 9, 2023

    @bufdev
    Author

    Oh, that'd be great then if possible :-) But no worries either way. One suggestion: If you do expose Tree directly, some type of iterator-type function to iterate over what are now the traceFrames for the both Trace and Children would be fantastic, but I won't get picky.

  3. abhinav commented on Dec 11, 2023

    @abhinav
    Contributor

    @bufdev Just confirming one thing for what you were trying to do: you didn't need to know/track the parent/child relationships between errors, right? You just wanted errors and their traces?

  4. bufdev commented on Dec 11, 2023

    @bufdev
    Author

    Yea I'm not interested in the relationships between the errors.

  5. prashantv commented on Dec 12, 2023

    @prashantv
    Contributor

    Since we allow annotating an error with a specific frame, I wonder if we should expose the converse -- an API that extracts a single frame from an error (if it's an errtrace wrapped error). The caller can then build up the same tree by unwrapping.

    I'm OK with also having more APIs to expose the tree, though I'd start with the lowest-level first, then the more common need (customization options for formatting).

  6. abhinav commented on Dec 12, 2023

    @abhinav
    Contributor

    I like starting with that.
    Strawman:

    // UnwrapFrame unwraps the errtrace frame
    // stored inside the given error.
    //
    // inner is the error inside the errtrace, if any.
    // ok reports whether a frame was available.
    func UnwrapFrame(error) (inner error, frame Frame, ok bool)

    (I want to not take the name "unwrap" in case we want to provide an errors.Unwrap analog per #38 (comment).)

    So a user could do something like:

    // func printTrace(w io.Writer, err error) {
    
    err, frame, ok := UnwrapFrame(err)
    for ok {
      printFrame(w, frame)
      err, frame, ok = UnwrapFrame(err)
    }
    
    if err == nil {
      // end of stack
      return
    }
    
    if multi, ok := err.(interface{ Unwrap() []error }); ok {
      for _, err := range multi.Unwrap() {
        fmt.Fprintln(w) // separate traces with newlines
        printTrace(w, err)
      }
    }
  7. added a commit that references this issue on Apr 15, 2024
  8. added a commit that references this issue on May 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions