// Package errors implements the KeyCape error taxonomy from spec §5. // All profile errors are structured and machine-readable. // Errors MUST NOT be silent — every unsupported or misused feature returns a typed error. package errors import ( "encoding/json" "net/http" ) // ErrorType is a stable string identifier for profile error categories. type ErrorType string const ( // ErrFeatureNotSupported is returned when a feature is outside the NetKingdom IAM Profile. ErrFeatureNotSupported ErrorType = "feature_not_supported_by_profile" // ErrKeycloakModeOnly is returned when a feature exists only in expanded (Keycloak) mode. ErrKeycloakModeOnly ErrorType = "available_in_keycloak_mode_only" // ErrRejectedForSafety is returned when a feature is intentionally blocked for security reasons. ErrRejectedForSafety ErrorType = "rejected_for_profile_safety" // ErrInvalidProfileUsage is returned when a supported endpoint/feature is used incorrectly. ErrInvalidProfileUsage ErrorType = "invalid_profile_usage" ) // ProfileError is a structured error per spec §5.2. // JSON format: {"error": "...", "description": "...", "feature": "..."} type ProfileError struct { Error ErrorType `json:"error"` Description string `json:"description"` Feature string `json:"feature,omitempty"` } // Write writes the error as JSON with the given HTTP status code. func (e *ProfileError) Write(w http.ResponseWriter, status int) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(e) } // GoError implements the standard error interface. func (e *ProfileError) GoError() string { if e.Feature != "" { return string(e.Error) + ": " + e.Description + " [feature=" + e.Feature + "]" } return string(e.Error) + ": " + e.Description } // FeatureNotSupported constructs a feature_not_supported_by_profile error. func FeatureNotSupported(description, feature string) *ProfileError { return &ProfileError{ Error: ErrFeatureNotSupported, Description: description, Feature: feature, } } // KeycloakModeOnly constructs an available_in_keycloak_mode_only error. func KeycloakModeOnly(description, feature string) *ProfileError { return &ProfileError{ Error: ErrKeycloakModeOnly, Description: description, Feature: feature, } } // RejectedForSafety constructs a rejected_for_profile_safety error. func RejectedForSafety(description, feature string) *ProfileError { return &ProfileError{ Error: ErrRejectedForSafety, Description: description, Feature: feature, } } // InvalidProfileUsage constructs an invalid_profile_usage error. func InvalidProfileUsage(description, feature string) *ProfileError { return &ProfileError{ Error: ErrInvalidProfileUsage, Description: description, Feature: feature, } }