Skip to content

Archive

Go

3 articles
Go 02 Sep 2026 7 min read

Short Reads and Exact-Length I/O in Go

Reading bytes in Go looks simple: allocate a buffer, call Read, and inspect the error. The subtlety is that io.Reader does not promise to fill the buffer in one call. A valid reader may return fewer bytes than requested even when more data will arrive later. That behavior matters for network protocols, binary file formats, framed messages, and any code that expects an exact number of bytes. Correct stream handling starts by matching the API to the requirement: use ordinary Read when partial progress is acceptable, and use helpers such as io.ReadFull when a fixed-size field must be complete.

Go 02 Sep 2026 4 min read

Reading Streams Correctly in Go with io.Reader

Go’s io.Reader interface is tiny: type Reader interface { Read(p []byte) (n int, err error) } Its small surface hides an important contract: a read is allowed to return fewer bytes than the buffer can hold, and it can return useful bytes together with an error. Correct stream processing must handle both cases.

Go 01 Sep 2026 2 min read

Preserve Cancellation Causes with context.WithCancelCause in Go

Go’s context.Context propagates deadlines and cancellation across API boundaries. Traditional cancellation tells downstream work that it should stop, but ctx.Err() only reports context.Canceled or context.DeadlineExceeded. Sometimes the reason matters. Go 1.20 introduced context.WithCancelCause, and later releases added cause-aware deadline helpers. They preserve a domain error without changing normal cancellation behavior. Attach a cause to cancellation package main import ( "context" "errors" "fmt" ) var ErrSuperseded = errors.New("request superseded") func main() { ctx, cancel := context.WithCancelCause(context.Background()) cancel(ErrSuperseded) fmt.Println(ctx.Err()) // context canceled fmt.Println(context.Cause(ctx)) // request superseded } Code that only understands Context still sees ordinary cancellation. Code that needs diagnostic detail can call context.Cause.