[GH-ISSUE #222] [BUG] Panics lack context #1094

Closed
opened 2026-03-07 22:05:37 +03:00 by kerem · 1 comment
Owner

Originally created by @bojanz on GitHub (Jan 6, 2021).
Original GitHub issue: https://github.com/hibiken/asynq/issues/222

Originally assigned to: @hibiken on GitHub.

Describe the bug
Asynq's panic handling only logs the error, without any stack trace information:

	defer func() {
		if x := recover(); x != nil {
			err = fmt.Errorf("panic: %v", x)
		}
	}()

This can make it difficult to debug a panic, which is often generic (e.g. "runtime error: invalid memory address or nil pointer dereference").

Could we at least add the triggering line and file to the output? That would look something like this:

	defer func() {
		if x := recover(); x != nil {
                        // Skip the first frame (the panic func itself).
                        _, file, line, _ := runtime.Caller(1)
                        // The panic came from the runtime, most likely due to incorrect
	                // map/slice usage. The parent frame should have the real trigger.
	                if strings.HasPrefix(file, "runtime/") {
		                _, file, line, _ = runtime.Caller(2)
	                }
			err = fmt.Errorf("panic [%v:%v]: %v", file, line, x)
		}
	}()

Since this is still just a suggestion, I did not test the runtime.Caller() line to see if we're skipping the right number of stacks, the numbers might need to be bumped by 1.

Originally created by @bojanz on GitHub (Jan 6, 2021). Original GitHub issue: https://github.com/hibiken/asynq/issues/222 Originally assigned to: @hibiken on GitHub. **Describe the bug** Asynq's panic handling only logs the error, without any stack trace information: ``` defer func() { if x := recover(); x != nil { err = fmt.Errorf("panic: %v", x) } }() ``` This can make it difficult to debug a panic, which is often generic (e.g. "runtime error: invalid memory address or nil pointer dereference"). Could we at least add the triggering line and file to the output? That would look something like this: ``` defer func() { if x := recover(); x != nil { // Skip the first frame (the panic func itself). _, file, line, _ := runtime.Caller(1) // The panic came from the runtime, most likely due to incorrect // map/slice usage. The parent frame should have the real trigger. if strings.HasPrefix(file, "runtime/") { _, file, line, _ = runtime.Caller(2) } err = fmt.Errorf("panic [%v:%v]: %v", file, line, x) } }() ``` Since this is still just a suggestion, I did not test the runtime.Caller() line to see if we're skipping the right number of stacks, the numbers might need to be bumped by 1.
kerem 2026-03-07 22:05:37 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@hibiken commented on GitHub (Jan 6, 2021):

@bojanz Thank you for pointing this out!
I'll see if we can include more meaningful context in the error itself.
At a minimum we should be logging the panic info when we recover from a panic.

<!-- gh-comment-id:755778965 --> @hibiken commented on GitHub (Jan 6, 2021): @bojanz Thank you for pointing this out! I'll see if we can include more meaningful context in the error itself. At a minimum we should be logging the panic info when we recover from a panic.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/asynq#1094
No description provided.