CodexBloom - Programming Q&A Platform

Handling Context Cancellation in Go with HTTP Middleware - Unexpected Behavior

πŸ‘€ Views: 0 πŸ’¬ Answers: 1 πŸ“… Created: 2025-06-13
go http context middleware Go

I've tried everything I can think of but I tried several approaches but none seem to work. I'm currently working on a Go application that uses the `net/http` package to handle incoming requests. I’m trying to implement a middleware that utilizes context cancellation to ensure that ongoing operations are aborted if the request context is cancelled. However, I'm experiencing some unexpected behavior when the context is cancelled before my long-running operation finishes. Here's a simplified version of my middleware: ```go package main import ( "context" "fmt" "net/http" "time" ) func timeoutMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second) defer cancel() // Simulate a long-running operation select { case <-time.After(3 * time.Second): // Operation exceeds timeout http.Error(w, "Request timed out", http.StatusGatewayTimeout) case <-ctx.Done(): // Context cancelled if err := ctx.Err(); err == context.Canceled { http.Error(w, "Request cancelled", http.StatusRequestTimeout) } } }) } func main() { mux := http.NewServeMux() mux.Handle("/process", timeoutMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Processing...") }))) http.ListenAndServe(":8080", mux) } ``` When I test this middleware by sending a request and then cancelling it by closing the connection (like stopping the request from the client-side before obtaining the response), I expect the context’s cancellation to trigger and return a "Request cancelled" message. However, I still receive the "Request timed out" error instead, even when I cancel the request before the timeout. I've tried adjusting the timeout duration and ensuring the middleware is correctly placed in the handler chain, but the behavior remains the same. Is there something I'm missing regarding how context cancellation works in this scenario? Any insights would be greatly appreciated. What's the best practice here? For reference, this is a production microservice. I appreciate any insights!