Skip to content
This repository was archived by the owner on Dec 1, 2021. It is now read-only.

proposal: change for Go beginners (stack trace)Β #140

Closed
@pierrre

Description

@pierrre

What I understand

  • WithMessage() adds a message
  • WithStack() adds the current stack
  • Wrap[f]() adds a message + stack
  • New|Errorf() creates an new error with message + stack

History

If I remember correctly:

  • Wrap[f]() was added first
  • WithMessage() + WithStack() were added later, because Wrap[f]() was "too much" => we don't need a stack trace for all "wrapped error". It is only useful for the "deepest" error.

When should we use each function

  • New root error => New|Errorf() (it will contain a stack trace)
  • Error returned by the std lib or a 3rd party lib => Wrap[f]() (we want to add a stack trace)
  • Error returned by our own code (in my app) => WithMessage() (we don't want to add more stack trace)
  • Error returned by a different goroutine => WithStack() (I don't use it very often)

Who am I working with

  • ~10 Go developers
  • All beginners in Go (they were working with other languages previously)
  • Not always very strict/careful

The problem

  • They don't/can't understand where to use Wrap[f]() vs WithMessage()
  • We're losing a lot of time during code review
    • Checking if Wrap[f]() or WithMessage() should be called
    • Explaining in which case we must use which function
    • Starting again for each newcomer

The risks

  • If we call WithMessage() instead of Wrap[f]() => we're missing the stack trace
  • If we call Wrap[f]() instead of WithMessage() => we "pollute" our error logs

What we need

A function that wraps an error with a message, and optionnaly with a stack trace if it doesn't have already one.

What I tried

My initial idea was to write a custom helper function that would do as described previously.
Sadly, this is not easily doable.
I can't call WithStack() or Wrap[f]() because it would include the helper function call in the stack.

The solutions

New function

Add a new function to github.com/pkg/errors, that is exactly like Wrap[f](), but doesn't add a stack trace if there is already one.

I don't really like this one, because it makes the package's interface more complex

Change behavior

Change Wrap[f](), and don't add a stack trace if there is already one.

This is my favorite solution.

I agree, it will change the existing behavior.
However, I think this is worth it.
I can't think of any use case that requires to call Wrap[f]() several times and have several redundant stack traces.

Just fork

I can perfectly understand if you disagree, and don't want to update the current code.
In this case, I will just copy the code to our internal repo, and adapt the code to match our needs.

I don't really like this, because I would stop using github.com/pkg/errors.
We're currently using it everywhere in our code.
I've been able to "extend" the behavior properly since the beginning.

The implementation

I've seen #122 and I really dislike the implementation.
It means that only internal github.com/pkg/errors types can be used.
We can't create our own types anymore.

What I would do instead:

  • iterates over all causes
  • check if at least 1 error implements StackTrace()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions