Skip to content

Commit e7af436

Browse files
committed
fix: address review - add docstrings, deep stack test, log dropped notifications
- Add docstrings to all customError methods for coverage threshold - Add TestStackDepthCappedDeep with recursive calls exceeding 64 frames to exercise the capping logic - Log at debug level when async notifications are dropped due to semaphore capacity, aiding observability during sustained bursts
1 parent 30c5f49 commit e7af436

3 files changed

Lines changed: 29 additions & 3 deletions

File tree

errors.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,37 +54,42 @@ type customError struct {
5454
status *grpcstatus.Status
5555
}
5656

57-
// implements notifier.NotifyExt
57+
// ShouldNotify returns true if the error should be reported to notifiers.
5858
func (c *customError) ShouldNotify() bool {
5959
return c.shouldNotify
6060
}
6161

62-
// implements notifier.NotifyExt
62+
// Notified marks the error as having been notified (or not).
6363
func (c *customError) Notified(status bool) {
6464
c.shouldNotify = !status
6565
}
6666

67-
// implements error
67+
// Error returns the error message.
6868
func (c customError) Error() string {
6969
return c.Msg
7070
}
7171

72+
// Callers returns the program counters of the call stack when the error was created.
7273
func (c customError) Callers() []uintptr {
7374
return c.stack[:]
7475
}
7576

77+
// StackTrace returns the program counters of the call stack (alias for Callers).
7678
func (c customError) StackTrace() []uintptr {
7779
return c.Callers()
7880
}
7981

82+
// StackFrame returns the structured stack frames for the error.
8083
func (c customError) StackFrame() []StackFrame {
8184
return c.frame
8285
}
8386

87+
// Cause returns the root cause error that originated this error chain.
8488
func (c customError) Cause() error {
8589
return c.cause
8690
}
8791

92+
// GRPCStatus returns the gRPC status for this error.
8893
func (c customError) GRPCStatus() *grpcstatus.Status {
8994
if c.status != nil {
9095
// use latest error message and keep other data (e.g. details)
@@ -121,6 +126,7 @@ func (c *customError) generateStack(skip int) []StackFrame {
121126
return stack
122127
}
123128

129+
// Unwrap returns the immediate parent error for use with errors.Is and errors.As.
124130
func (c customError) Unwrap() error {
125131
return c.wrapped
126132
}

errors_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,22 @@ func TestStackDepthCapped(t *testing.T) {
112112
}
113113
}
114114

115+
func TestStackDepthCappedDeep(t *testing.T) {
116+
var createDeepError func(depth int) ErrorExt
117+
createDeepError = func(depth int) ErrorExt {
118+
if depth == 0 {
119+
return New("deep error")
120+
}
121+
return createDeepError(depth - 1)
122+
}
123+
124+
// Create error from a stack deeper than 64
125+
err := createDeepError(100)
126+
if len(err.StackFrame()) > 64 {
127+
t.Errorf("stack depth %d exceeds max 64", len(err.StackFrame()))
128+
}
129+
if len(err.StackFrame()) == 0 {
130+
t.Error("stack should not be empty")
131+
}
132+
}
133+

notifier/notifier.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func NotifyAsync(err error, rawData ...interface{}) error {
6565
}(sem)
6666
default:
6767
// drop notification to prevent goroutine explosion
68+
log.Debug(context.Background(), "msg", "async notification dropped due to capacity", "err", err)
6869
}
6970
return err
7071
}

0 commit comments

Comments
 (0)