Error handling for Go HTTP servers — structured error responses, error wrapping,
88
81%
Does it follow best practices?
Impact
99%
1.80xAverage score across 5 eval scenarios
Passed
No known issues
{
"context": "Tests whether the agent proactively adds production-grade error handling (custom error types, recovery middleware, structured JSON error responses, error wrapping, graceful shutdown) when building a standard Go CRUD API that does not mention error handling in the requirements.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Custom error type",
"description": "A custom error type (e.g. AppError) is defined with at least StatusCode, Code, and Message fields, and implements the error interface",
"max_score": 12
},
{
"name": "Unwrap method",
"description": "The custom error type implements an Unwrap() method that returns the wrapped inner error, enabling errors.Is and errors.As to traverse the error chain",
"max_score": 8
},
{
"name": "Structured JSON error response",
"description": "All error responses are JSON with a consistent shape containing at least a code and message field (e.g. {\"error\": {\"code\": \"...\", \"message\": \"...\"}}). No bare http.Error calls or plain text error responses.",
"max_score": 12
},
{
"name": "writeError helper",
"description": "A dedicated helper function (e.g. writeError) is used by all handlers to write error responses, rather than each handler formatting errors inline",
"max_score": 10
},
{
"name": "Recovery middleware",
"description": "A recovery middleware using defer/recover catches panics and returns a structured 500 JSON response instead of crashing the server",
"max_score": 12
},
{
"name": "Graceful shutdown",
"description": "The server handles SIGTERM and/or SIGINT signals and calls srv.Shutdown with a timeout context to drain in-flight requests",
"max_score": 8
},
{
"name": "No internal error leaks",
"description": "Internal/unexpected errors return a generic message to the client (e.g. 'An unexpected error occurred') -- no raw error strings, stack traces, or internal details are exposed in response bodies",
"max_score": 10
},
{
"name": "Appropriate status codes",
"description": "Different error types return correct HTTP status codes: 400 for validation, 404 for not found, 409 for duplicate SKU, 422 or 400 for insufficient stock, 500 for unexpected -- not all mapped to the same code",
"max_score": 10
},
{
"name": "Validation with detail",
"description": "Validation errors for the create/update endpoints include information about which fields failed and why, not just a generic 'bad request' message",
"max_score": 8
},
{
"name": "Error wrapping with %w",
"description": "When errors are wrapped with fmt.Errorf, the %w verb is used (not %v) to preserve the error chain",
"max_score": 5
},
{
"name": "All endpoints functional",
"description": "All six endpoints are implemented and return appropriate success status codes (200 for reads, 201 for creation, 200/204 for delete)",
"max_score": 5
}
]
}