Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user to skip (ignore) specific caller frames in assert.CallerInfo() #1527

Open
xuxife opened this issue Jan 30, 2024 · 4 comments
Open

Comments

@xuxife
Copy link

xuxife commented Jan 30, 2024

Hi, I notice my assertion failure message sometimes has loooong stack traces, where most of them are from sdk or framework.
I hope there could be a feature that I can customize assert.CallerInfo(), such that I can focus the stacks in my codebase.

for instance, allow a package-level callback like SkipCallerFrame(pc uintptr, file, line string) bool to skip the frame if the callback returns true.

	callers := []string{}
	for i := 0; ; i++ {
		pc, file, line, ok = runtime.Caller(i)
		if !ok {
			// The breaks below failed to terminate the loop, and we ran off the
			// end of the call stack.
			break
		}

             +  if SkipCallerFrame(pc, file, line) {
             +          break
             +  }
		// This is a huge edge case, but it will panic if this is the case, see #180
		if file == "<autogenerated>" {
			break
		}

		f := runtime.FuncForPC(pc)
		if f == nil {
			break
		}
		name = f.Name()

		// testing.tRunner is the standard library function that calls
		// tests. Subtests are called directly by tRunner, without going through
		// the Test/Benchmark/Example function that contains the t.Run calls, so
		// with subtests we should break when we hit tRunner, without adding it
		// to the list of callers.
		if name == "testing.tRunner" {
			break
		}
@brackendawson
Copy link
Collaborator

An aside: I'm pretty sure CallerInfo isn't supposed to be exported. I've noted this in #1431.

How long is too long? Can you show us an example? In go 1.21 the Go runtime chose to only print the first and last 50 frames: https://tip.golang.org/doc/go1.21#runtime-changes We could emulate that.

@dolmen
Copy link
Collaborator

dolmen commented May 16, 2024

An aside: I'm pretty sure CallerInfo isn't supposed to be exported. I've noted this in #1431.

I agree, but CallerInfo appears to be heavily used in the wild: https://github.com/search?q=assert.CallerInfo%28%29+lang%3AGo+&type=code

@brackendawson
Copy link
Collaborator

brackendawson commented Oct 5, 2024

Go 1.21 introduced a runtime change to only show the top and bottom 50: https://tip.golang.org/doc/go1.21#runtime-changes. Maybe could just emulate this.

Can you quantify loooong @xuxife?

@xuxife
Copy link
Author

xuxife commented Oct 8, 2024

Nice to known @brackendawson !
For instance, I was using github.com/Azure/azure-sdk-for-go,
Only first several (~5) inner stacks are useful, maybe that's a mock http call in test code.
Then following (~20) stacks are repetitive in policy.Request.Next in sdk code.
Finally, the outer most stacks are useful again because that's where my production code calls sdk.
So I was hoping a feature for CallerInfo to ignore the medium stacks conditionally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants