dojo.md 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/courses/GENERATION_LOG.md +27 -0
- package/courses/api-error-handling/course.yaml +16 -0
- package/courses/api-error-handling/scenarios/level-1/error-response-format.yaml +131 -0
- package/courses/api-error-handling/scenarios/level-1/http-status-codes-basics.yaml +90 -0
- package/courses/api-error-handling/scenarios/level-1/rate-limiting-basics.yaml +135 -0
- package/courses/api-error-handling/scenarios/level-1/request-validation-errors.yaml +208 -0
- package/courses/api-error-handling/scenarios/level-2/circuit-breaker-pattern.yaml +189 -0
- package/courses/api-error-handling/scenarios/level-2/idempotency-retry-logic.yaml +159 -0
- package/courses/api-error-handling/scenarios/level-2/rfc-7807-problem-details.yaml +178 -0
- package/courses/api-error-handling/scenarios/level-2/webhook-error-handling.yaml +211 -0
- package/courses/api-error-handling/scenarios/level-3/distributed-tracing-errors.yaml +275 -0
- package/courses/github-actions-cicd/course.yaml +10 -0
- package/courses/github-actions-cicd/scenarios/level-1/actions-and-runners.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-1/basic-workflow-syntax.yaml +52 -0
- package/courses/github-actions-cicd/scenarios/level-1/branch-protection-checks.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-1/environment-variables-secrets.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-1/first-cicd-shift.yaml +62 -0
- package/courses/github-actions-cicd/scenarios/level-1/job-dependencies-outputs.yaml +62 -0
- package/courses/github-actions-cicd/scenarios/level-1/simple-ci-pipeline.yaml +57 -0
- package/courses/github-actions-cicd/scenarios/level-1/workflow-debugging.yaml +90 -0
- package/courses/github-actions-cicd/scenarios/level-1/workflow-status-notifications.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-1/workflow-triggers.yaml +56 -0
- package/courses/github-actions-cicd/scenarios/level-2/concurrency-control.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-2/conditional-execution.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-2/custom-actions-development.yaml +55 -0
- package/courses/github-actions-cicd/scenarios/level-2/dependency-caching.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-2/deployment-workflows.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-2/github-packages-publishing.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-2/intermediate-cicd-shift.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-2/matrix-builds.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-2/reusable-workflows.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-2/workflow-cost-optimization.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-3/advanced-cicd-shift.yaml +64 -0
- package/courses/github-actions-cicd/scenarios/level-3/compliance-automation.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-3/docker-action-development.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-3/github-environments.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-3/monorepo-ci.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-3/oidc-cloud-deployments.yaml +55 -0
- package/courses/github-actions-cicd/scenarios/level-3/release-automation.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-3/security-hardening.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-3/self-hosted-runners.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-3/workflow-optimization.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-data-architecture.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-economics-roi.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-executive-communication.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-incident-response.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-org-design.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-platform-architecture.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-training-program.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-vendor-evaluation.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-4/enterprise-cicd-governance.yaml +55 -0
- package/courses/github-actions-cicd/scenarios/level-4/expert-cicd-shift.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-ai-future.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-behavioral-science.yaml +70 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-board-strategy.yaml +56 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-consulting-engagement.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-industry-benchmarks.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-ma-integration.yaml +73 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-product-development.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-regulatory-landscape.yaml +72 -0
- package/courses/github-actions-cicd/scenarios/level-5/comprehensive-cicd-system.yaml +66 -0
- package/courses/github-actions-cicd/scenarios/level-5/master-cicd-shift.yaml +76 -0
- package/courses/github-pr-review/scenarios/level-2/api-change-review.yaml +82 -0
- package/courses/github-pr-review/scenarios/level-2/automated-review-tooling.yaml +53 -0
- package/courses/github-pr-review/scenarios/level-2/cross-team-review.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-2/intermediate-review-shift.yaml +66 -0
- package/courses/github-pr-review/scenarios/level-2/performance-review-patterns.yaml +99 -0
- package/courses/github-pr-review/scenarios/level-2/review-disagreement-resolution.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-2/review-metrics-analysis.yaml +63 -0
- package/courses/github-pr-review/scenarios/level-2/review-turnaround-sla.yaml +54 -0
- package/courses/github-pr-review/scenarios/level-2/stacked-pr-review.yaml +65 -0
- package/courses/github-pr-review/scenarios/level-3/advanced-review-shift.yaml +65 -0
- package/courses/github-pr-review/scenarios/level-3/ai-powered-review.yaml +58 -0
- package/courses/github-pr-review/scenarios/level-3/compliance-review-process.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-3/cross-functional-review.yaml +60 -0
- package/courses/github-pr-review/scenarios/level-3/incident-driven-review.yaml +63 -0
- package/courses/github-pr-review/scenarios/level-3/large-scale-review-operations.yaml +55 -0
- package/courses/github-pr-review/scenarios/level-3/monorepo-review-process.yaml +68 -0
- package/courses/github-pr-review/scenarios/level-3/review-automation-platform.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-3/review-culture-design.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-3/review-data-pipeline.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-4/enterprise-review-operations.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-4/expert-review-shift.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-4/review-data-architecture.yaml +69 -0
- package/courses/github-pr-review/scenarios/level-4/review-economics-roi.yaml +63 -0
- package/courses/github-pr-review/scenarios/level-4/review-executive-communication.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-4/review-incident-postmortem.yaml +69 -0
- package/courses/github-pr-review/scenarios/level-4/review-org-design.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-4/review-platform-architecture.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-4/review-training-program.yaml +66 -0
- package/courses/github-pr-review/scenarios/level-4/review-vendor-evaluation.yaml +76 -0
- package/courses/github-pr-review/scenarios/level-5/comprehensive-review-system.yaml +68 -0
- package/courses/github-pr-review/scenarios/level-5/master-review-shift.yaml +73 -0
- package/courses/github-pr-review/scenarios/level-5/review-ai-future.yaml +69 -0
- package/courses/github-pr-review/scenarios/level-5/review-behavioral-science.yaml +66 -0
- package/courses/github-pr-review/scenarios/level-5/review-board-strategy.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-5/review-consulting-engagement.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-5/review-devtools-product.yaml +71 -0
- package/courses/github-pr-review/scenarios/level-5/review-industry-benchmarks.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-5/review-ma-integration.yaml +76 -0
- package/courses/github-pr-review/scenarios/level-5/review-regulatory-landscape.yaml +78 -0
- package/courses/postgresql-query-optimization/course.yaml +11 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/explain-analyze-basics.yaml +80 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/first-optimization-shift.yaml +77 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/index-fundamentals.yaml +76 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/join-basics.yaml +73 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/n-plus-one-queries.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/query-rewriting-basics.yaml +69 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/select-star-problems.yaml +69 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/slow-query-diagnosis.yaml +63 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/vacuum-and-statistics.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/where-clause-optimization.yaml +74 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/autovacuum-tuning.yaml +76 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/composite-index-design.yaml +81 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/covering-indexes.yaml +74 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/cte-optimization.yaml +83 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/intermediate-optimization-shift.yaml +66 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/join-optimization.yaml +72 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/partial-and-expression-indexes.yaml +75 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/query-planner-settings.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/subquery-optimization.yaml +67 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/window-function-optimization.yaml +63 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/advanced-optimization-shift.yaml +71 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/connection-pooling.yaml +60 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/full-text-search-optimization.yaml +66 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/jsonb-optimization.yaml +88 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/lock-contention-analysis.yaml +80 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/materialized-view-optimization.yaml +73 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/parallel-query-execution.yaml +74 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/partitioning-strategies.yaml +71 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/specialized-index-types.yaml +67 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/write-optimization.yaml +65 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/data-architecture-analytics.yaml +64 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/database-executive-communication.yaml +64 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/database-migration-planning.yaml +57 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/enterprise-database-governance.yaml +52 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/expert-optimization-shift.yaml +73 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/high-availability-architecture.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/optimizer-internals.yaml +69 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/performance-sla-design.yaml +58 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/read-replica-optimization.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/vendor-evaluation.yaml +73 -0
- package/courses/rest-api-error-handling/course.yaml +11 -0
- package/courses/rest-api-error-handling/scenarios/level-1/authentication-errors.yaml +71 -0
- package/courses/rest-api-error-handling/scenarios/level-1/content-negotiation-errors.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-1/error-logging-basics.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-1/error-response-format.yaml +58 -0
- package/courses/rest-api-error-handling/scenarios/level-1/first-error-handling-shift.yaml +67 -0
- package/courses/rest-api-error-handling/scenarios/level-1/http-status-codes.yaml +46 -0
- package/courses/rest-api-error-handling/scenarios/level-1/not-found-errors.yaml +52 -0
- package/courses/rest-api-error-handling/scenarios/level-1/rate-limiting-errors.yaml +56 -0
- package/courses/rest-api-error-handling/scenarios/level-1/request-validation-errors.yaml +59 -0
- package/courses/rest-api-error-handling/scenarios/level-1/server-error-handling.yaml +55 -0
- package/courses/rest-api-error-handling/scenarios/level-2/api-versioning-errors.yaml +66 -0
- package/courses/rest-api-error-handling/scenarios/level-2/batch-request-errors.yaml +61 -0
- package/courses/rest-api-error-handling/scenarios/level-2/circuit-breaker-pattern.yaml +52 -0
- package/courses/rest-api-error-handling/scenarios/level-2/error-code-taxonomy.yaml +62 -0
- package/courses/rest-api-error-handling/scenarios/level-2/error-monitoring-alerting.yaml +53 -0
- package/courses/rest-api-error-handling/scenarios/level-2/intermediate-error-shift.yaml +69 -0
- package/courses/rest-api-error-handling/scenarios/level-2/pagination-errors.yaml +66 -0
- package/courses/rest-api-error-handling/scenarios/level-2/retry-and-idempotency.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-2/rfc7807-problem-details.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-2/webhook-error-handling.yaml +55 -0
- package/courses/rest-api-error-handling/scenarios/level-3/advanced-error-shift.yaml +72 -0
- package/courses/rest-api-error-handling/scenarios/level-3/api-gateway-errors.yaml +71 -0
- package/courses/rest-api-error-handling/scenarios/level-3/async-api-errors.yaml +67 -0
- package/courses/rest-api-error-handling/scenarios/level-3/caching-error-scenarios.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-3/chaos-engineering-apis.yaml +62 -0
- package/courses/rest-api-error-handling/scenarios/level-3/database-error-handling.yaml +79 -0
- package/courses/rest-api-error-handling/scenarios/level-3/distributed-error-propagation.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-3/error-budgets-sre.yaml +61 -0
- package/courses/rest-api-error-handling/scenarios/level-3/error-correlation.yaml +58 -0
- package/courses/rest-api-error-handling/scenarios/level-3/graphql-vs-rest-errors.yaml +73 -0
- package/courses/rest-api-error-handling/scenarios/level-4/compliance-error-handling.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-4/enterprise-error-governance.yaml +62 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-analytics-platform.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-cost-optimization.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-executive-communication.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-handling-architecture.yaml +67 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-org-design.yaml +68 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-sla-design.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-training-program.yaml +61 -0
- package/courses/rest-api-error-handling/scenarios/level-4/expert-error-shift.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-5/comprehensive-error-system.yaml +68 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-ai-future.yaml +75 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-behavioral-science.yaml +73 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-board-strategy.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-consulting-engagement.yaml +58 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-industry-benchmarks.yaml +72 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-ma-integration.yaml +68 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-product-development.yaml +66 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-regulatory-landscape.yaml +80 -0
- package/courses/rest-api-error-handling/scenarios/level-5/master-error-shift.yaml +73 -0
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +6 -5
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +4 -0
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +6 -18
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/train.d.ts.map +1 -1
- package/dist/cli/commands/train.js +18 -18
- package/dist/cli/commands/train.js.map +1 -1
- package/dist/cli/index.js +93 -55
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/run-demo.js +2 -1
- package/dist/cli/run-demo.js.map +1 -1
- package/dist/cli/setup.d.ts +18 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +154 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/engine/agent-bridge.d.ts +5 -2
- package/dist/engine/agent-bridge.d.ts.map +1 -1
- package/dist/engine/agent-bridge.js +36 -9
- package/dist/engine/agent-bridge.js.map +1 -1
- package/dist/engine/loader.d.ts +21 -0
- package/dist/engine/loader.d.ts.map +1 -1
- package/dist/engine/loader.js +54 -1
- package/dist/engine/loader.js.map +1 -1
- package/dist/engine/training-loop.d.ts.map +1 -1
- package/dist/engine/training-loop.js +1 -0
- package/dist/engine/training-loop.js.map +1 -1
- package/dist/engine/training.d.ts.map +1 -1
- package/dist/engine/training.js +1 -0
- package/dist/engine/training.js.map +1 -1
- package/dist/generator/skill-generator.d.ts +1 -1
- package/dist/generator/skill-generator.d.ts.map +1 -1
- package/dist/generator/skill-generator.js +21 -2
- package/dist/generator/skill-generator.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +11 -26
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/session-manager.d.ts +3 -1
- package/dist/mcp/session-manager.d.ts.map +1 -1
- package/dist/mcp/session-manager.js +44 -22
- package/dist/mcp/session-manager.js.map +1 -1
- package/dist/types/schemas.d.ts +38 -13
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +9 -5
- package/dist/types/schemas.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: request-validation-errors
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle request validation errors — implement input validation with clear, actionable error messages for API consumers"
|
|
7
|
+
tags: [REST, API, validation, error-messages, input, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're building a user registration endpoint for an e-commerce API.
|
|
13
|
+
The endpoint POST /users accepts:
|
|
14
|
+
|
|
15
|
+
{
|
|
16
|
+
"email": "string (required, valid email)",
|
|
17
|
+
"password": "string (required, 8-64 chars, 1 uppercase, 1 number)",
|
|
18
|
+
"name": "string (required, 2-100 chars)",
|
|
19
|
+
"phone": "string (optional, E.164 format)",
|
|
20
|
+
"date_of_birth": "string (optional, ISO 8601, must be 13+)",
|
|
21
|
+
"referral_code": "string (optional, 8 alphanumeric chars)"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
A frontend developer sends this request and gets back a 400 error
|
|
25
|
+
with the message "Invalid input" — nothing else. They're frustrated:
|
|
26
|
+
"Which field is wrong? What's wrong with it? How do I fix it?"
|
|
27
|
+
|
|
28
|
+
Test cases to handle:
|
|
29
|
+
1. Empty body: {}
|
|
30
|
+
2. Missing required fields: { "email": "test@example.com" }
|
|
31
|
+
3. Invalid email: { "email": "not-an-email", "password": "Abc12345",
|
|
32
|
+
"name": "Jo" }
|
|
33
|
+
4. Weak password: { "email": "a@b.com", "password": "short",
|
|
34
|
+
"name": "Jo" }
|
|
35
|
+
5. Multiple errors: { "email": "bad", "password": "x", "name": "",
|
|
36
|
+
"phone": "12345", "date_of_birth": "not-a-date" }
|
|
37
|
+
6. Valid request with unknown extra fields:
|
|
38
|
+
{ "email": "a@b.com", "password": "Abc12345", "name": "Jo",
|
|
39
|
+
"admin": true, "role": "superuser" }
|
|
40
|
+
|
|
41
|
+
Task: Write the validation error responses for all 6 test cases.
|
|
42
|
+
Each response should tell the consumer exactly what's wrong and
|
|
43
|
+
how to fix it. Then write the validation strategy: should you fail
|
|
44
|
+
on the first error or collect all errors? How do you handle unknown
|
|
45
|
+
fields? What about nested objects?
|
|
46
|
+
|
|
47
|
+
assertions:
|
|
48
|
+
- type: llm_judge
|
|
49
|
+
criteria: "Error responses are field-specific and actionable — each validation error names the exact field, describes what's wrong, and indicates what's expected. Multiple errors are returned together (not fail-fast) so the consumer can fix everything in one attempt"
|
|
50
|
+
weight: 0.35
|
|
51
|
+
description: "Field-specific actionable errors"
|
|
52
|
+
- type: llm_judge
|
|
53
|
+
criteria: "All 6 test cases produce appropriate responses — empty body lists all required fields, missing fields identifies which are missing, invalid formats explain the expected format, multiple errors are collected into an array, and unknown fields are handled safely (stripped or rejected with explanation)"
|
|
54
|
+
weight: 0.35
|
|
55
|
+
description: "All test cases handled"
|
|
56
|
+
- type: llm_judge
|
|
57
|
+
criteria: "Validation strategy is well-reasoned — explains collect-all-errors approach, addresses unknown/extra field handling (security implications of accepting 'admin: true'), and considers validation ordering (format before business logic)"
|
|
58
|
+
weight: 0.30
|
|
59
|
+
description: "Well-reasoned validation strategy"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: server-error-handling
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle 5xx server errors — implement safe error handling for unexpected failures without exposing internals"
|
|
7
|
+
tags: [REST, API, 5xx, server-errors, error-handling, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're on-call when the monitoring dashboard lights up. Your API is
|
|
13
|
+
returning 500 errors with full stack traces in the response body.
|
|
14
|
+
A customer screenshots one and posts it on Twitter:
|
|
15
|
+
|
|
16
|
+
{
|
|
17
|
+
"error": "DatabaseError: connection refused to postgres://admin:
|
|
18
|
+
s3cretP@ss@db-prod-01.internal.company.com:5432/users_db",
|
|
19
|
+
"stack": "at Pool.connect (/app/node_modules/pg/lib/pool.js:332)\n
|
|
20
|
+
at UserService.getUser (/app/src/services/user.ts:47)\n
|
|
21
|
+
at UserController.get (/app/src/controllers/user.ts:23)\n..."
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
The tweet goes viral. Security is panicking because the response
|
|
25
|
+
exposed: database credentials, internal hostnames, database name,
|
|
26
|
+
technology stack (Node.js, pg, TypeScript), and code structure.
|
|
27
|
+
|
|
28
|
+
Your team lead wants you to fix this immediately. The API has these
|
|
29
|
+
failure modes that can cause 500 errors:
|
|
30
|
+
1. Database connection failures
|
|
31
|
+
2. Unhandled null pointer exceptions in business logic
|
|
32
|
+
3. Third-party API timeouts (payment processor)
|
|
33
|
+
4. Out of memory errors during large report generation
|
|
34
|
+
5. File system permission errors when writing uploads
|
|
35
|
+
|
|
36
|
+
Task: Write the global error handler that catches all unhandled
|
|
37
|
+
errors and returns safe responses. Show: the safe 500 error response
|
|
38
|
+
format (what the client sees), the server-side error logging format
|
|
39
|
+
(what goes to your logging system), how to add request correlation
|
|
40
|
+
IDs so support can link a user's error to the server log, and how
|
|
41
|
+
each of the 5 failure modes should be handled differently.
|
|
42
|
+
|
|
43
|
+
assertions:
|
|
44
|
+
- type: llm_judge
|
|
45
|
+
criteria: "Safe error responses never expose internals — no stack traces, database credentials, internal hostnames, technology details, or code structure in client-facing responses. Returns a generic message with a correlation ID that support can use to look up the full error"
|
|
46
|
+
weight: 0.35
|
|
47
|
+
description: "Safe error responses"
|
|
48
|
+
- type: llm_judge
|
|
49
|
+
criteria: "Server-side logging captures full diagnostic information — logs stack trace, error type, request details, correlation ID, and context. The 5 failure modes are handled differently where appropriate (503 for DB/third-party failures vs 500 for unhandled exceptions)"
|
|
50
|
+
weight: 0.35
|
|
51
|
+
description: "Comprehensive server-side logging"
|
|
52
|
+
- type: llm_judge
|
|
53
|
+
criteria: "Correlation ID system is well-designed — explains how IDs are generated (UUID), how they flow through the request lifecycle, how they appear in both the error response and server logs, and how support uses them to debug customer-reported errors"
|
|
54
|
+
weight: 0.30
|
|
55
|
+
description: "Correlation ID system"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: api-versioning-errors
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle API versioning errors — manage error responses during API version transitions and deprecation"
|
|
7
|
+
tags: [REST, API, versioning, deprecation, migration, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your API is migrating from v1 to v2. The changes include:
|
|
13
|
+
- Different error response format (custom JSON → RFC 7807)
|
|
14
|
+
- Some endpoints removed (POST /users/bulk → use /users/import)
|
|
15
|
+
- Field renames (user.firstName → user.first_name)
|
|
16
|
+
- Stricter validation (email regex is now RFC 5322 compliant)
|
|
17
|
+
- New required fields (POST /orders now requires shipping_address)
|
|
18
|
+
|
|
19
|
+
Timeline:
|
|
20
|
+
- v2 launched 3 months ago
|
|
21
|
+
- v1 sunset in 6 months
|
|
22
|
+
- Currently 60% of traffic is v1, 40% is v2
|
|
23
|
+
|
|
24
|
+
Customer issues during the migration:
|
|
25
|
+
|
|
26
|
+
1. Customer sends v1-format request to v2 endpoint:
|
|
27
|
+
POST /v2/users { "firstName": "John" }
|
|
28
|
+
Gets 400 but doesn't understand why (field was renamed)
|
|
29
|
+
|
|
30
|
+
2. Customer uses removed v1 endpoint:
|
|
31
|
+
POST /v1/users/bulk [...]
|
|
32
|
+
Gets 404 (endpoint already removed from v1 ahead of schedule)
|
|
33
|
+
|
|
34
|
+
3. Customer on v1 gets different error format than v2 customer
|
|
35
|
+
for the same underlying issue — confusing for shared tooling
|
|
36
|
+
|
|
37
|
+
4. Customer tries to use v2 features via v1:
|
|
38
|
+
POST /v1/orders { "shipping_method": "express" }
|
|
39
|
+
(shipping_method only exists in v2)
|
|
40
|
+
|
|
41
|
+
5. v1 validation passes but v2 validation rejects the same input
|
|
42
|
+
(stricter email regex)
|
|
43
|
+
|
|
44
|
+
6. No version specified:
|
|
45
|
+
POST /users { ... }
|
|
46
|
+
Which version should be assumed?
|
|
47
|
+
|
|
48
|
+
Task: Design the versioning error handling strategy. Write: how
|
|
49
|
+
each of the 6 issues should be handled (status codes, error
|
|
50
|
+
messages, migration hints), the deprecation warning system (headers,
|
|
51
|
+
response fields), the sunset timeline communication in error
|
|
52
|
+
responses, and the version negotiation logic.
|
|
53
|
+
|
|
54
|
+
assertions:
|
|
55
|
+
- type: llm_judge
|
|
56
|
+
criteria: "All 6 versioning issues have clear solutions — renamed fields get migration hints in the error message, removed endpoints return 410 Gone (not 404) with the replacement URL, version-specific validation differences are documented in errors, and missing version defaults are clearly defined"
|
|
57
|
+
weight: 0.35
|
|
58
|
+
description: "All versioning issues solved"
|
|
59
|
+
- type: llm_judge
|
|
60
|
+
criteria: "Deprecation communication is proactive — uses Sunset header (RFC 8594) and Deprecation header, includes deprecation warnings on successful v1 responses (not just errors), and provides migration documentation links in responses"
|
|
61
|
+
weight: 0.35
|
|
62
|
+
description: "Proactive deprecation communication"
|
|
63
|
+
- type: llm_judge
|
|
64
|
+
criteria: "Version negotiation is well-designed — explains how to handle missing version (default policy), URL path vs header vs query param versioning approach, and how the error format itself should be versioned (v1 clients get v1 errors, v2 clients get RFC 7807)"
|
|
65
|
+
weight: 0.30
|
|
66
|
+
description: "Well-designed version negotiation"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: batch-request-errors
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle batch request errors — design error responses when some items in a batch succeed and others fail"
|
|
7
|
+
tags: [REST, API, batch, partial-failure, bulk-operations, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your CRM API has a batch endpoint for importing contacts:
|
|
13
|
+
POST /contacts/batch with an array of up to 1,000 contacts.
|
|
14
|
+
|
|
15
|
+
A customer imports 500 contacts and gets back a 400 error:
|
|
16
|
+
{ "error": "Validation failed" }
|
|
17
|
+
|
|
18
|
+
They're frustrated: "Which contacts failed? The 490 valid ones
|
|
19
|
+
didn't get created either. I have to fix the 10 bad ones and
|
|
20
|
+
re-submit all 500?"
|
|
21
|
+
|
|
22
|
+
Scenarios to handle:
|
|
23
|
+
|
|
24
|
+
1. All 500 succeed — easy case
|
|
25
|
+
2. 10 of 500 fail validation (duplicate emails, missing required
|
|
26
|
+
fields) — what happens to the other 490?
|
|
27
|
+
3. 250 succeed, then the database goes down — 250 are created,
|
|
28
|
+
250 are not. What's the response?
|
|
29
|
+
4. Request contains 2,000 contacts (over the 1,000 limit)
|
|
30
|
+
5. One contact has an email that triggers a rate limit on the
|
|
31
|
+
email verification service — should it block the whole batch?
|
|
32
|
+
6. Request is 50MB (massive batch) — how to handle before even
|
|
33
|
+
parsing
|
|
34
|
+
|
|
35
|
+
Design decisions needed:
|
|
36
|
+
- All-or-nothing (transaction) vs partial success?
|
|
37
|
+
- What HTTP status code for partial success? (200? 207? 202?)
|
|
38
|
+
- How to report per-item errors while keeping the response
|
|
39
|
+
navigable?
|
|
40
|
+
- How to handle the case where the client needs to retry only
|
|
41
|
+
the failed items?
|
|
42
|
+
|
|
43
|
+
Task: Design the batch error handling system. Write: the batch
|
|
44
|
+
response format (showing per-item success/failure), the HTTP status
|
|
45
|
+
code strategy, the error detail for each of the 6 scenarios, the
|
|
46
|
+
transaction vs partial-success decision (with trade-offs), and the
|
|
47
|
+
retry guidance for failed items.
|
|
48
|
+
|
|
49
|
+
assertions:
|
|
50
|
+
- type: llm_judge
|
|
51
|
+
criteria: "Batch response format is clear — each item in the batch has an individual success/failure status with the item's index or identifier, specific error details for failed items, and a summary (total, succeeded, failed). The format allows clients to identify and retry only failed items"
|
|
52
|
+
weight: 0.35
|
|
53
|
+
description: "Clear batch response format"
|
|
54
|
+
- type: llm_judge
|
|
55
|
+
criteria: "All 6 scenarios have appropriate responses — full success (200/201), partial failure with a suitable status code (207 Multi-Status or similar), request too large (413), database mid-batch failure is handled (either transactionally or with clear partial status), and the rate limit scenario is isolated to the affected item"
|
|
56
|
+
weight: 0.35
|
|
57
|
+
description: "All scenarios handled"
|
|
58
|
+
- type: llm_judge
|
|
59
|
+
criteria: "Transaction vs partial-success trade-off is well-analyzed — discusses when all-or-nothing is appropriate (financial operations) vs when partial success is better (data imports), and the chosen approach is justified for the CRM contact import use case. Retry guidance tells clients how to re-submit only failed items"
|
|
60
|
+
weight: 0.30
|
|
61
|
+
description: "Well-analyzed trade-offs"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: circuit-breaker-pattern
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Implement circuit breaker pattern — prevent cascading failures when downstream services fail"
|
|
7
|
+
tags: [REST, API, circuit-breaker, resilience, cascading-failures, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your e-commerce API depends on 5 downstream services. Last Tuesday,
|
|
13
|
+
the recommendation service went down for 30 minutes. Because your
|
|
14
|
+
API makes a synchronous call to it on every product page request,
|
|
15
|
+
ALL product pages became unusable — 100% failure rate when only the
|
|
16
|
+
recommendation service (a non-critical feature) was down.
|
|
17
|
+
|
|
18
|
+
The cascade:
|
|
19
|
+
1. Recommendation service starts timing out (30s timeout)
|
|
20
|
+
2. Your API's thread pool fills up waiting for recommendations
|
|
21
|
+
3. No threads available to serve product data (which is fine)
|
|
22
|
+
4. Users see 504 Gateway Timeout on all product pages
|
|
23
|
+
5. Cart and checkout also slow down (shared thread pool)
|
|
24
|
+
6. Revenue loss: $150,000 in 30 minutes
|
|
25
|
+
|
|
26
|
+
Your downstream services:
|
|
27
|
+
- Product catalog (critical): 99.95% uptime, 50ms p99
|
|
28
|
+
- Inventory (critical): 99.9% uptime, 100ms p99
|
|
29
|
+
- Recommendations (nice-to-have): 99.5% uptime, 200ms p99
|
|
30
|
+
- Reviews (nice-to-have): 99.7% uptime, 150ms p99
|
|
31
|
+
- Pricing (critical): 99.95% uptime, 75ms p99
|
|
32
|
+
|
|
33
|
+
Task: Design the circuit breaker system. Write: the circuit breaker
|
|
34
|
+
configuration for each service (thresholds, timeouts, fallbacks),
|
|
35
|
+
the state machine (closed → open → half-open), the fallback
|
|
36
|
+
strategies for each service (what to return when the circuit is
|
|
37
|
+
open), the error responses when circuit breakers are active, and
|
|
38
|
+
the monitoring dashboard that shows circuit breaker state.
|
|
39
|
+
|
|
40
|
+
assertions:
|
|
41
|
+
- type: llm_judge
|
|
42
|
+
criteria: "Circuit breaker design differentiates by criticality — critical services (catalog, inventory, pricing) have different thresholds and fallback strategies than nice-to-have services (recommendations, reviews). Nice-to-have services fail open with degraded responses, critical services may fail closed with proper error responses"
|
|
43
|
+
weight: 0.35
|
|
44
|
+
description: "Criticality-aware circuit breaker"
|
|
45
|
+
- type: llm_judge
|
|
46
|
+
criteria: "State machine is complete — defines closed (normal), open (failing fast), and half-open (testing recovery) states with specific thresholds (failure count/percentage, timeout window, half-open success count). Explains what triggers each state transition"
|
|
47
|
+
weight: 0.35
|
|
48
|
+
description: "Complete state machine"
|
|
49
|
+
- type: llm_judge
|
|
50
|
+
criteria: "Fallback strategies are practical — recommendations return empty array or cached data, reviews show 'reviews unavailable', critical service failures return clear error responses. Error responses indicate degraded mode to clients. Monitoring shows real-time circuit state"
|
|
51
|
+
weight: 0.30
|
|
52
|
+
description: "Practical fallback strategies"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: error-code-taxonomy
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Design an error code taxonomy — create a structured system of application-level error codes beyond HTTP status codes"
|
|
7
|
+
tags: [REST, API, error-codes, taxonomy, documentation, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your fintech API returns HTTP status codes but customers want more
|
|
13
|
+
granular error identification. They're asking: "I got a 400 — but
|
|
14
|
+
was it a missing field, an invalid format, a business rule violation,
|
|
15
|
+
or a duplicate request? I need to handle each differently in my
|
|
16
|
+
code."
|
|
17
|
+
|
|
18
|
+
Examples of why HTTP status codes alone aren't enough:
|
|
19
|
+
|
|
20
|
+
All of these return 400 Bad Request:
|
|
21
|
+
- Missing required field (title)
|
|
22
|
+
- Invalid email format
|
|
23
|
+
- Amount exceeds daily transfer limit ($10,000)
|
|
24
|
+
- Transfer to self not allowed
|
|
25
|
+
- Account is in read-only mode (regulatory hold)
|
|
26
|
+
- Duplicate idempotency key
|
|
27
|
+
|
|
28
|
+
All of these return 403 Forbidden:
|
|
29
|
+
- User doesn't have the 'transfers' permission
|
|
30
|
+
- IP address not in allowlist
|
|
31
|
+
- Account requires 2FA for this operation
|
|
32
|
+
- Compliance hold on account
|
|
33
|
+
- Operation not available in user's country
|
|
34
|
+
|
|
35
|
+
Customer requirements:
|
|
36
|
+
- "I need machine-readable codes I can switch on in my code"
|
|
37
|
+
- "I need to show different UI messages for different errors"
|
|
38
|
+
- "I need to know if the error is permanent or temporary"
|
|
39
|
+
- "I need error codes to be stable — don't change them without
|
|
40
|
+
warning"
|
|
41
|
+
- "I need documentation for every error code"
|
|
42
|
+
|
|
43
|
+
Task: Design the error code taxonomy. Write: the naming convention
|
|
44
|
+
(format, namespacing by domain), the complete error code catalog
|
|
45
|
+
for the examples above, the error code documentation template,
|
|
46
|
+
the governance process (how new codes are added, how existing
|
|
47
|
+
codes are deprecated), and the client SDK integration (how error
|
|
48
|
+
codes map to typed exceptions).
|
|
49
|
+
|
|
50
|
+
assertions:
|
|
51
|
+
- type: llm_judge
|
|
52
|
+
criteria: "Error code system is well-structured — uses a consistent format (e.g., DOMAIN_CATEGORY_SPECIFIC like TRANSFER_LIMIT_EXCEEDED), is hierarchical enough for programmatic handling, and each code maps to a specific HTTP status code. Distinguishes between transient and permanent errors"
|
|
53
|
+
weight: 0.35
|
|
54
|
+
description: "Well-structured error code system"
|
|
55
|
+
- type: llm_judge
|
|
56
|
+
criteria: "Error catalog is complete and documented — all examples from the trigger are assigned codes, each code has a description, common causes, resolution steps, and whether it's retryable. Documentation template is thorough enough for API consumers to self-serve"
|
|
57
|
+
weight: 0.35
|
|
58
|
+
description: "Complete documented catalog"
|
|
59
|
+
- type: llm_judge
|
|
60
|
+
criteria: "Governance and SDK integration are practical — defines who can create new codes, versioning policy for codes, deprecation process, and shows how error codes translate to typed exceptions in client SDKs (making switch statements possible)"
|
|
61
|
+
weight: 0.30
|
|
62
|
+
description: "Practical governance and SDK integration"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: error-monitoring-alerting
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Set up error monitoring and alerting — build an alerting system that catches real issues without alert fatigue"
|
|
7
|
+
tags: [REST, API, monitoring, alerting, observability, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your API team has a monitoring problem: too many alerts that nobody
|
|
13
|
+
acts on. Last month, the team received 2,847 alerts. Of those:
|
|
14
|
+
- 2,100 were "5xx error rate above 0.1%" (most were single errors)
|
|
15
|
+
- 400 were "response time above 500ms" (during daily batch jobs)
|
|
16
|
+
- 200 were "disk space above 80%" (on log servers, always at 82%)
|
|
17
|
+
- 100 were "connection pool exhausted" (recovered in seconds)
|
|
18
|
+
- 47 were real incidents requiring action
|
|
19
|
+
|
|
20
|
+
The real incidents that were missed or delayed because of alert
|
|
21
|
+
fatigue:
|
|
22
|
+
- Payment endpoint returning 500 for 15 minutes (buried in noise)
|
|
23
|
+
- Database connection leak causing gradual degradation over 3 hours
|
|
24
|
+
- Authentication service returning wrong 200 responses (not caught
|
|
25
|
+
by status code monitoring)
|
|
26
|
+
- Third-party API silently returning stale data
|
|
27
|
+
|
|
28
|
+
Your API handles:
|
|
29
|
+
- 10M requests/day across 30 endpoints
|
|
30
|
+
- Baseline error rate: 0.05% (mostly 404s from bots)
|
|
31
|
+
- P99 latency: 200ms (varies by endpoint)
|
|
32
|
+
- 5 downstream dependencies
|
|
33
|
+
|
|
34
|
+
Task: Redesign the alerting system. Write: the alert taxonomy
|
|
35
|
+
(severity levels and routing), the specific alert rules for each
|
|
36
|
+
error category (with thresholds that avoid false positives), the
|
|
37
|
+
escalation policy, the dashboard design for real-time error
|
|
38
|
+
visibility, and the process for tuning alerts as traffic patterns
|
|
39
|
+
change.
|
|
40
|
+
|
|
41
|
+
assertions:
|
|
42
|
+
- type: llm_judge
|
|
43
|
+
criteria: "Alert taxonomy reduces noise — defines severity levels (critical/warning/info) with clear criteria, routes alerts appropriately (PagerDuty for critical, Slack for warning, dashboard for info), and the new thresholds would have caught the 47 real incidents while eliminating most of the 2,800 false alerts"
|
|
44
|
+
weight: 0.35
|
|
45
|
+
description: "Noise-reducing alert taxonomy"
|
|
46
|
+
- type: llm_judge
|
|
47
|
+
criteria: "Alert rules are specific and contextual — uses error rate changes (not absolute thresholds), per-endpoint alerting (not global), anomaly detection for latency, and monitors for correctness issues (like the authentication service returning wrong 200s). Addresses the 4 missed incidents specifically"
|
|
48
|
+
weight: 0.35
|
|
49
|
+
description: "Specific contextual alert rules"
|
|
50
|
+
- type: llm_judge
|
|
51
|
+
criteria: "Escalation and tuning process is practical — defines who gets alerted at each severity, time-based escalation for unacknowledged alerts, and a regular process for reviewing alert effectiveness (false positive rate, mean time to detect)"
|
|
52
|
+
weight: 0.30
|
|
53
|
+
description: "Practical escalation and tuning"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: intermediate-error-shift
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Intermediate error handling shift — manage a complex multi-service outage with cascading error scenarios"
|
|
7
|
+
tags: [REST, API, error-handling, shift-simulation, outage, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're the on-call engineer for a travel booking API. It's peak
|
|
13
|
+
summer booking season and the system processes $2M in bookings daily.
|
|
14
|
+
At 2:15 PM, alerts start firing.
|
|
15
|
+
|
|
16
|
+
Timeline of events:
|
|
17
|
+
|
|
18
|
+
2:15 PM — Hotel availability service starts returning 503
|
|
19
|
+
- Error rate: 100% on hotel searches
|
|
20
|
+
- Impact: Users can't search hotels, but flights still work
|
|
21
|
+
- Root cause unknown
|
|
22
|
+
|
|
23
|
+
2:20 PM — The booking service starts timing out
|
|
24
|
+
- Users who already found hotels are trying to book
|
|
25
|
+
- Booking service calls hotel availability to verify → timeout
|
|
26
|
+
- Bookings in progress are hanging (payment already charged but
|
|
27
|
+
booking not confirmed)
|
|
28
|
+
|
|
29
|
+
2:25 PM — Payment service reports "orphaned charges"
|
|
30
|
+
- 47 customers were charged but bookings weren't created
|
|
31
|
+
- Refund system requires a booking ID to process refunds
|
|
32
|
+
- Manual refund takes 3-5 business days
|
|
33
|
+
|
|
34
|
+
2:30 PM — Customer support flooded
|
|
35
|
+
- "I was charged $500 but have no booking confirmation"
|
|
36
|
+
- "The search page is spinning forever"
|
|
37
|
+
- "I booked a flight but can't add a hotel"
|
|
38
|
+
- API consumers (partner sites) are getting 504s from your gateway
|
|
39
|
+
|
|
40
|
+
2:35 PM — You discover the hotel service's database ran out of
|
|
41
|
+
connections due to a connection leak in a deploy at 1:45 PM
|
|
42
|
+
|
|
43
|
+
Available actions:
|
|
44
|
+
- Roll back hotel service to previous version
|
|
45
|
+
- Enable circuit breaker to bypass hotel availability check
|
|
46
|
+
- Manually refund the 47 orphaned charges
|
|
47
|
+
- Return cached hotel data (stale by 2 hours)
|
|
48
|
+
- Put up a maintenance page
|
|
49
|
+
|
|
50
|
+
Task: Handle this incident from the API error handling perspective.
|
|
51
|
+
Write: the immediate error response changes for each endpoint
|
|
52
|
+
during the outage, the orphaned payment recovery plan, the
|
|
53
|
+
customer communication (API status page updates), the partner
|
|
54
|
+
API consumer communication, and the post-incident improvements
|
|
55
|
+
to prevent this error cascade.
|
|
56
|
+
|
|
57
|
+
assertions:
|
|
58
|
+
- type: llm_judge
|
|
59
|
+
criteria: "Immediate response handles each service appropriately — hotel search returns 503 with Retry-After (or cached data with staleness indicator), booking endpoint returns clear error about hotel unavailability without charging, existing orphaned payments are identified and handled, and flight-only flows remain functional"
|
|
60
|
+
weight: 0.35
|
|
61
|
+
description: "Appropriate immediate response"
|
|
62
|
+
- type: llm_judge
|
|
63
|
+
criteria: "Orphaned payment recovery is thorough — identifies all 47 affected customers, has a plan to refund without booking IDs (use payment timestamps), communicates proactively to affected customers, and designs a reconciliation process to catch any missed orphans"
|
|
64
|
+
weight: 0.35
|
|
65
|
+
description: "Thorough payment recovery"
|
|
66
|
+
- type: llm_judge
|
|
67
|
+
criteria: "Post-incident improvements prevent cascade — circuit breakers to isolate hotel service failures, payment-before-booking flow redesigned (or compensating transactions), connection pool monitoring and alerting, and deploy-time health checks that would have caught the connection leak"
|
|
68
|
+
weight: 0.30
|
|
69
|
+
description: "Cascade prevention improvements"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: pagination-errors
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle pagination errors — design error responses for cursor-based and offset-based pagination edge cases"
|
|
7
|
+
tags: [REST, API, pagination, cursor, offset, edge-cases, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your social media API supports both offset-based and cursor-based
|
|
13
|
+
pagination. Users are hitting confusing edge cases:
|
|
14
|
+
|
|
15
|
+
Bug reports this sprint:
|
|
16
|
+
|
|
17
|
+
1. Offset out of range: GET /posts?offset=999999&limit=20
|
|
18
|
+
Returns: 200 { "data": [], "total": 500 }
|
|
19
|
+
User says: "Is this an error? Should I get 404? How do I know
|
|
20
|
+
I've gone past the end?"
|
|
21
|
+
|
|
22
|
+
2. Negative offset: GET /posts?offset=-5&limit=20
|
|
23
|
+
Returns: 500 Internal Server Error (database throws)
|
|
24
|
+
|
|
25
|
+
3. Limit too large: GET /posts?limit=10000
|
|
26
|
+
Returns: 200 (but takes 45 seconds and OOMs the server)
|
|
27
|
+
|
|
28
|
+
4. Invalid cursor: GET /posts?cursor=abc123invalid
|
|
29
|
+
Returns: 200 { "data": [] }
|
|
30
|
+
User says: "Is the cursor expired or invalid? Same response
|
|
31
|
+
as 'no more data'."
|
|
32
|
+
|
|
33
|
+
5. Expired cursor: GET /posts?cursor=eyJ0... (valid format but
|
|
34
|
+
references a deleted post)
|
|
35
|
+
Returns: 500 with database error
|
|
36
|
+
|
|
37
|
+
6. Both offset and cursor provided:
|
|
38
|
+
GET /posts?offset=10&cursor=eyJ0...
|
|
39
|
+
Returns: uses offset, ignores cursor (confusing)
|
|
40
|
+
|
|
41
|
+
7. Data changes during pagination: User fetches page 1, new posts
|
|
42
|
+
are added, page 2 has duplicates from page 1
|
|
43
|
+
|
|
44
|
+
8. Zero limit: GET /posts?limit=0
|
|
45
|
+
Returns: 200 { "data": [], "total": 500 }
|
|
46
|
+
(Wastes a database query)
|
|
47
|
+
|
|
48
|
+
Task: Design the error handling for all 8 pagination edge cases.
|
|
49
|
+
For each, decide: is it an error or expected behavior? What status
|
|
50
|
+
code? What response? Then write pagination error handling guidelines
|
|
51
|
+
that cover both offset-based and cursor-based approaches, including
|
|
52
|
+
the response format that helps clients paginate correctly.
|
|
53
|
+
|
|
54
|
+
assertions:
|
|
55
|
+
- type: llm_judge
|
|
56
|
+
criteria: "Each of the 8 edge cases has a clear, reasoned response — 400 for invalid parameters (negative offset, zero limit, conflicting params), enforced max limit to prevent OOM, distinct responses for invalid vs expired cursors (not the same as 'no more data'), and offset-out-of-range returns empty array with metadata showing total"
|
|
57
|
+
weight: 0.35
|
|
58
|
+
description: "All 8 edge cases handled"
|
|
59
|
+
- type: llm_judge
|
|
60
|
+
criteria: "Pagination response format prevents client confusion — includes total count, has_more flag, next_cursor or next_offset, and clear indication when the client has reached the end of results. The format makes it impossible to confuse 'no more data' with 'invalid request'"
|
|
61
|
+
weight: 0.35
|
|
62
|
+
description: "Clear pagination format"
|
|
63
|
+
- type: llm_judge
|
|
64
|
+
criteria: "Guidelines cover both pagination styles — explains trade-offs between offset and cursor pagination, how each handles data consistency (the duplicate data problem), and recommends cursor-based for feeds/timelines and offset-based for stable datasets with known totals"
|
|
65
|
+
weight: 0.30
|
|
66
|
+
description: "Comprehensive pagination guidelines"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: retry-and-idempotency
|
|
3
|
+
level: 2
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Design retry and idempotency patterns — build resilient API error recovery without duplicate side effects"
|
|
7
|
+
tags: [REST, API, retry, idempotency, resilience, intermediate]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your payment processing API has a critical bug: when the network
|
|
13
|
+
drops between your server and the payment processor, the client
|
|
14
|
+
retries and customers get charged twice. This has happened 47 times
|
|
15
|
+
in the last month, costing $12,000 in refunds and significant
|
|
16
|
+
customer trust.
|
|
17
|
+
|
|
18
|
+
The flow that's failing:
|
|
19
|
+
1. Client: POST /payments { amount: 100, card: "..." }
|
|
20
|
+
2. Server: calls Stripe to charge $100 → succeeds
|
|
21
|
+
3. Server: tries to respond 200 to client → network timeout
|
|
22
|
+
4. Client: sees timeout, retries POST /payments { same data }
|
|
23
|
+
5. Server: calls Stripe again → charges another $100
|
|
24
|
+
6. Customer charged $200 instead of $100
|
|
25
|
+
|
|
26
|
+
Your API has these endpoints that need retry safety:
|
|
27
|
+
- POST /payments — charge a customer
|
|
28
|
+
- POST /orders — create an order (generates order number)
|
|
29
|
+
- POST /refunds — issue a refund
|
|
30
|
+
- PUT /orders/:id/status — update order status
|
|
31
|
+
- POST /notifications/send — send push notification
|
|
32
|
+
- DELETE /orders/:id — cancel an order
|
|
33
|
+
|
|
34
|
+
Questions from the team:
|
|
35
|
+
1. "Which endpoints need idempotency keys and which are naturally
|
|
36
|
+
idempotent?"
|
|
37
|
+
2. "Where do we store the idempotency keys? Redis? Database?"
|
|
38
|
+
3. "How long do we keep them? Forever?"
|
|
39
|
+
4. "What if two concurrent requests have the same idempotency key?"
|
|
40
|
+
5. "What status codes should trigger a client retry vs not?"
|
|
41
|
+
|
|
42
|
+
Task: Design the idempotency and retry system. Write: which
|
|
43
|
+
endpoints need idempotency keys (with reasoning), the idempotency
|
|
44
|
+
key implementation (storage, TTL, concurrency handling), the client
|
|
45
|
+
retry policy (which status codes to retry, backoff strategy), and
|
|
46
|
+
the API error responses that communicate retry safety to clients.
|
|
47
|
+
|
|
48
|
+
assertions:
|
|
49
|
+
- type: llm_judge
|
|
50
|
+
criteria: "Idempotency analysis is correct — POST /payments and POST /orders need idempotency keys, PUT is naturally idempotent, DELETE is naturally idempotent, POST /refunds needs keys. Explains why GET is safe, PUT is safe, and POST is dangerous for retries"
|
|
51
|
+
weight: 0.35
|
|
52
|
+
description: "Correct idempotency analysis"
|
|
53
|
+
- type: llm_judge
|
|
54
|
+
criteria: "Implementation handles edge cases — addresses concurrent duplicate requests (locking), idempotency key TTL (not forever, with rationale), storage choice (Redis vs DB with trade-offs), what to return when a duplicate request arrives (cached response vs 409), and how to handle in-flight requests"
|
|
55
|
+
weight: 0.35
|
|
56
|
+
description: "Edge case handling"
|
|
57
|
+
- type: llm_judge
|
|
58
|
+
criteria: "Client retry policy is specific — lists retryable status codes (503, 429, 408, network errors) and non-retryable codes (400, 401, 403, 404, 409, 422), includes exponential backoff with jitter, sets max retry count, and the error responses include Retry-After headers where appropriate"
|
|
59
|
+
weight: 0.30
|
|
60
|
+
description: "Specific client retry policy"
|