CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/graceful-degradation

Every external call needs a timeout, every timeout needs a fallback — resilience patterns for HTTP, databases, and third-party services

88

4.72x
Quality

90%

Does it follow best practices?

Impact

85%

4.72x

Average score across 5 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-5/

{
  "context": "Tests whether the agent proactively applies graceful degradation patterns when building a dashboard that aggregates three external APIs. The task only describes business requirements -- fetching weather, stocks, and news. It says nothing about timeouts, fallbacks, error handling, or resilience. The agent should apply these patterns on its own.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "timeouts-on-all-fetches",
      "description": "Every fetch() call to an external API (OpenWeatherMap, Alpha Vantage, NewsAPI) includes an explicit timeout, such as signal: AbortSignal.timeout(ms) or an axios timeout option. No bare fetch() calls without a timeout.",
      "max_score": 15
    },
    {
      "name": "independent-error-handling",
      "description": "Each external service (weather, stocks, news) has its own try/catch or error handling. One service failing does not prevent the other services from returning data. Uses Promise.allSettled() or individual try/catch blocks per service, NOT Promise.all().",
      "max_score": 15
    },
    {
      "name": "partial-response-on-failure",
      "description": "When one or more services fail, the endpoint still returns a 200 response with available data and null/default values for failed services, rather than returning a 500 error.",
      "max_score": 15
    },
    {
      "name": "fallback-values-for-failed-services",
      "description": "Each service has a defined fallback value returned when it fails -- e.g., null, empty array, cached data, or an object with an unavailable flag. The catch block returns something meaningful, not just re-throws.",
      "max_score": 10
    },
    {
      "name": "warnings-field-in-response",
      "description": "The response includes a warnings, errors, or metadata field that lists which services are unavailable, so the client knows which data may be missing or stale.",
      "max_score": 10
    },
    {
      "name": "structured-error-logging",
      "description": "Caught failures are logged with structured context including the dependency name, the error message, and what fallback was used. Not just console.log(error).",
      "max_score": 10
    },
    {
      "name": "retry-with-backoff",
      "description": "At least one service call includes retry logic with exponential backoff (increasing delays between retries). Fixed-delay retries or no retries at all are a failure for this criterion.",
      "max_score": 10
    },
    {
      "name": "circuit-breaker-or-failure-tracking",
      "description": "A circuit breaker pattern or failure tracking mechanism is implemented for at least one dependency, so that repeated failures cause the service to short-circuit to the fallback without making the network call.",
      "max_score": 8
    },
    {
      "name": "per-service-timeout-config",
      "description": "Different services have or can have different timeout values based on their characteristics, rather than one hardcoded value everywhere. Timeout is configurable per service.",
      "max_score": 7
    }
  ]
}

evals

tile.json