mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 15:51:26 +00:00
- Stable machine-readable error codes alongside the error message (UNAUTHENTICATED, INVALID_TOKEN, ADMIN_REQUIRED, SCOPE_INSUFFICIENT, IDEMPOTENCY_IN_PROGRESS); CLI renders "CODE: message". - Idempotency middleware on authed/admin groups: POST requests with an Idempotency-Key header replay the first response for 24h (Redis-backed, caller-scoped); concurrent duplicates get 409. X-Idempotent-Replay header marks replays. - Shared pagination helpers: ?cursor= (opaque, preferred) alongside legacy ?page= on projects and deployments lists; pagination meta includes next_cursor; invalid cursors fail soft to page 1. - CLI --idempotency-key flag for safe scripted retries. - OpenAPI updated: error envelope, cursor params, idempotency contract. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
30 lines
979 B
Go
30 lines
979 B
Go
package api
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// Stable machine-readable error codes for agent clients. The "error" field
|
|
// stays human-readable; "code" is the contract the CLI/MCP rely on.
|
|
const (
|
|
CodeUnauthorized = "UNAUTHENTICATED"
|
|
CodeInvalidToken = "INVALID_TOKEN"
|
|
CodeForbidden = "FORBIDDEN"
|
|
CodeAdminRequired = "ADMIN_REQUIRED"
|
|
CodeScopeInsufficient = "SCOPE_INSUFFICIENT"
|
|
CodeNotFound = "NOT_FOUND"
|
|
CodeValidation = "VALIDATION"
|
|
CodeConflict = "CONFLICT"
|
|
CodeInternal = "INTERNAL"
|
|
CodeUnavailable = "DEPENDENCY_UNAVAILABLE"
|
|
CodeIdempotencyRunning = "IDEMPOTENCY_IN_PROGRESS"
|
|
)
|
|
|
|
// respondError emits the standard error envelope. Existing handlers return
|
|
// bare {"error": msg} — this adds the stable code for new and
|
|
// agent-facing paths.
|
|
func respondError(c *gin.Context, status int, code, message string) {
|
|
c.JSON(status, gin.H{"error": message, "code": code})
|
|
c.Abort()
|
|
}
|