// Otherwise Cause(c) returns the same value as c.Err().
// Cause returns nil if c has not been canceled yet.
func Cause(c Context) error {
+ err := c.Err()
+ if err == nil {
+ return nil
+ }
if cc, ok := c.Value(&cancelCtxKey).(*cancelCtx); ok {
cc.mu.Lock()
cause := cc.cause
if cause != nil {
return cause
}
- // Either this context is not canceled,
- // or it is canceled and the cancellation happened in a
- // custom context implementation rather than a *cancelCtx.
- }
- // There is no cancelCtxKey value with a cause, so we know that c is
- // not a descendant of some canceled Context created by WithCancelCause.
- // Therefore, there is no specific cause to return.
- // If this is not one of the standard Context types,
- // it might still have an error even though it won't have a cause.
- return c.Err()
+ // The parent cancelCtx doesn't have a cause,
+ // so c must have been canceled in some custom context implementation.
+ }
+ // We don't have a cause to return from a parent cancelCtx,
+ // so return the context's error.
+ return err
}
// AfterFunc arranges to call f in its own goroutine after ctx is canceled.