Tech News
← Back to articles

What canceled my Go context?

read original more articles

How Go 1.20's WithCancelCause and Go 1.21's WithTimeoutCause let you attach a reason to context cancellation, plus a gotcha with manual cancel and the stdlib pattern that covers every path.

I’ve spent way more hours than I’d like to admit debugging context canceled and context deadline exceeded errors. These errors usually tell you that a context was canceled, but not exactly why. In a typical client-server scenario, the reason could be any of the following:

The client disconnected

A parent deadline expired

The server started shutting down

Some code somewhere called cancel() explicitly

Go 1.20 and 1.21 added cause-tracking functions to the context package that fix this, but there’s a subtlety with WithTimeoutCause that most examples skip.

What “context canceled” actually tells you#

Here’s a function that processes an order by calling three services under a shared 5-second timeout:

func processOrder ( ctx context . Context , orderID string ) error { ctx , cancel := context . WithTimeout ( ctx , 5 * time . Second ) // (1) defer cancel () // (2) if err := checkInventory ( ctx , orderID ); err != nil { return err // (3) } if err := chargePayment ( ctx , orderID ); err != nil { return err } return shipOrder ( ctx , orderID ) }

... continue reading