CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/go-error-handling

Error handling for Go HTTP servers — structured error responses, error wrapping,

88

1.80x
Quality

81%

Does it follow best practices?

Impact

99%

1.80x

Average score across 5 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-2/

{
  "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
    }
  ]
}

evals

tile.json