Go Fundamentals - Sample
Table of Contents
Chapter 12.9: Context Errors
In a complex system, or even in a small one, when a context.Context
is cancelled, we need a way to know what caused the cancellation. It is possible that context.Context
was cancelled by a context.CancelFunc
successfully, if it was cancelled because it timed out, or some other reason.
The context.Context.Err
method, Listing 12.1 returns the error that caused the context to be cancelled.
$ go doc context.Context.Err
package context // import "context"
type Context interface {
// If Done is not yet closed, Err returns nil.
// If Done is closed, Err returns a non-nil error explaining why:
// Canceled if the context was canceled
// or DeadlineExceeded if the context's deadline passed.
// After Err returns a non-nil error, successive calls to Err return the same error.
Err() error
}
--------------------------------------------------------------------------------
Go Version: go1.23.0
context.Context.Err
method.Context Cancelled Error
The context
package defines two different error
variables that can be used to check an error
that was returned from context.Context.Err
method.
The first is context.Canceled
, Listing 12.2, which is returned when the context is cancelled through the use of a context.CancelFunc
function. This error
is considered to indicate a "successful" cancellation.
$ go doc context.Canceled
package context // import "context"
var Canceled = errors.New("context canceled")
Canceled is the error returned by [Context.Err] when the context is
canceled.
--------------------------------------------------------------------------------
Go Version: go1.23.0
context.Canceled
error
.Consider Listing 12.3. When we first check the context.Context.Err
method, it returns nil
. After we call the context.CancelFunc
function provided by context.WithCancel
, the context.Context.Err
method returns a context.Canceled
error.
func main() {
// create a background context
ctx := context.Background()
// wrap the context with a
// cancellable context
ctx, cancel := context.WithCancel(ctx)
// check the error:
//
fmt.Println("ctx.Err()", ctx.Err())
// cancel the context
cancel()
// check the error:
// context.Canceled
fmt.Println("ctx.Err()", ctx.Err())
// check the error again:
// context.Canceled
fmt.Println("ctx.Err()", ctx.Err())
}
$ go run .
ctx.Err() <nil>
ctx.Err() context canceled
ctx.Err() context canceled
--------------------------------------------------------------------------------
Go Version: go1.23.0
As we can see from the output in Listing 12.3, repeated calls to the context.Context.Err
method return the same context.Canceled
error.
Context Deadline Exceeded Error
When a context.Context
is cancelled due to a deadline, or timeout, being exceeded, the context.Context.Err
method returns a context.DeadlineExceeded
error, Listing 12.4.
$ go doc context.DeadlineExceeded
package context // import "context"
var DeadlineExceeded error = deadlineExceededError{}
DeadlineExceeded is the error returned by [Context.Err] when the context's
deadline passes.
--------------------------------------------------------------------------------
Go Version: go1.23.0
context.DeadlineExceeded
error
.Consider Listing 12.5. We create a context.Context
that will self cancel after 1 second. When we check context.Context.Err
method, before the context.Context
times out, it returns nil
.
func main() {
// create a background context
ctx := context.Background()
// wrap the context that will
// self cancel after 10 milliseconds
ctx, cancel := context.WithTimeout(ctx, 10*time.Millisecond)
defer cancel()
// check the error:
//
fmt.Println("ctx.Err()", ctx.Err())
// wait for the context to self cancel
<-ctx.Done()
// check the error:
// context.Canceled
fmt.Println("ctx.Err()", ctx.Err())
// check the error again:
// context.DeadlineExceeded
fmt.Println("ctx.Err()", ctx.Err())
}
$ go run .
ctx.Err() <nil>
ctx.Err() context deadline exceeded
ctx.Err() context deadline exceeded
--------------------------------------------------------------------------------
Go Version: go1.23.0
As we can see from the output, the context.Context
times out after the specified time, and the context.Context.Err
method returns a context.DeadlineExceeded
error.