Files
RUSTLE/ucxl_codes.go
anthonyrawlins 235ca68ee5 Initial RUSTLE implementation with UCXL Browser and standardized codes
- Complete UCXL protocol implementation with DHT storage layer
- BZZZ Gateway for peer-to-peer networking and content distribution
- Temporal navigation engine with version control and timeline browsing
- Standardized UCXL error/response codes for Rust, Go, and Python
- React-based UI with multi-tab interface and professional styling
- libp2p integration for distributed hash table operations
- Self-healing network mechanisms and peer management
- Comprehensive IPC commands for Tauri desktop integration

Major Components:
- ucxl-core: Core UCXL protocol and DHT implementation
- BZZZ Gateway: Local subnet peer discovery and content replication
- Temporal Engine: Version control and state reconstruction
- Cross-language standards: Unified error handling across implementations
- Modern UI: Professional React interface with DHT and network monitoring

Standards Compliance:
- UCXL-ERROR-CODES.md and UCXL-RESPONSE-CODES.md v1.0
- Machine-readable error codes with structured payloads
- Client guidance for retry logic and error handling
- Cross-language compatibility with identical APIs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-09 13:17:33 +10:00

422 lines
11 KiB
Go

// Package ucxl_codes provides standardized UCXL error and response codes
// for consistent cross-service communication and client handling.
//
// Based on UCXL-ERROR-CODES.md and UCXL-RESPONSE-CODES.md v1.0
package ucxl_codes
import (
"encoding/json"
"fmt"
"time"
"github.com/google/uuid"
)
// UCXLErrorCode represents standard UCXL error codes following format: UCXL-<HTTP-class>-<SHORT_NAME>
type UCXLErrorCode string
const (
// 400 - Client Errors
ErrorInvalidAddress UCXLErrorCode = "UCXL-400-INVALID_ADDRESS"
ErrorMissingField UCXLErrorCode = "UCXL-400-MISSING_FIELD"
ErrorInvalidFormat UCXLErrorCode = "UCXL-400-INVALID_FORMAT"
// 401 - Authentication
ErrorUnauthorized UCXLErrorCode = "UCXL-401-UNAUTHORIZED"
// 403 - Authorization
ErrorForbidden UCXLErrorCode = "UCXL-403-FORBIDDEN"
// 404 - Not Found
ErrorNotFound UCXLErrorCode = "UCXL-404-NOT_FOUND"
// 409 - Conflict
ErrorConflict UCXLErrorCode = "UCXL-409-CONFLICT"
// 422 - Unprocessable Entity
ErrorUnprocessableEntity UCXLErrorCode = "UCXL-422-UNPROCESSABLE_ENTITY"
// 429 - Rate Limiting
ErrorRateLimit UCXLErrorCode = "UCXL-429-RATE_LIMIT"
// 500 - Server Errors
ErrorInternalError UCXLErrorCode = "UCXL-500-INTERNAL_ERROR"
// 503 - Service Unavailable
ErrorServiceUnavailable UCXLErrorCode = "UCXL-503-SERVICE_UNAVAILABLE"
// 504 - Gateway Timeout
ErrorGatewayTimeout UCXLErrorCode = "UCXL-504-GATEWAY_TIMEOUT"
)
// UCXLResponseCode represents standard UCXL response codes following format: UCXL-<HTTP-class>-<SHORT_NAME>
type UCXLResponseCode string
const (
// 200 - Success
ResponseOK UCXLResponseCode = "UCXL-200-OK"
// 201 - Created
ResponseCreated UCXLResponseCode = "UCXL-201-CREATED"
// 202 - Accepted (Async)
ResponseAccepted UCXLResponseCode = "UCXL-202-ACCEPTED"
// 204 - No Content
ResponseNoContent UCXLResponseCode = "UCXL-204-NO_CONTENT"
// 206 - Partial Content
ResponsePartialContent UCXLResponseCode = "UCXL-206-PARTIAL_CONTENT"
// 304 - Not Modified (Caching)
ResponseNotModified UCXLResponseCode = "UCXL-304-NOT_MODIFIED"
)
// HTTPStatus returns the HTTP status code for the error code
func (e UCXLErrorCode) HTTPStatus() int {
switch e {
case ErrorInvalidAddress, ErrorMissingField, ErrorInvalidFormat:
return 400
case ErrorUnauthorized:
return 401
case ErrorForbidden:
return 403
case ErrorNotFound:
return 404
case ErrorConflict:
return 409
case ErrorUnprocessableEntity:
return 422
case ErrorRateLimit:
return 429
case ErrorInternalError:
return 500
case ErrorServiceUnavailable:
return 503
case ErrorGatewayTimeout:
return 504
default:
return 500
}
}
// DefaultMessage returns the default error message for this code
func (e UCXLErrorCode) DefaultMessage() string {
switch e {
case ErrorInvalidAddress:
return "Invalid UCXL address format"
case ErrorMissingField:
return "Required field is missing"
case ErrorInvalidFormat:
return "Input does not match the expected format"
case ErrorUnauthorized:
return "Authentication credentials missing or invalid"
case ErrorForbidden:
return "Insufficient permissions for the action"
case ErrorNotFound:
return "Requested resource not found"
case ErrorConflict:
return "Conflict with current state"
case ErrorUnprocessableEntity:
return "Semantic validation failed"
case ErrorRateLimit:
return "Too many requests; rate limiting in effect"
case ErrorInternalError:
return "Internal server error"
case ErrorServiceUnavailable:
return "Service is currently unavailable"
case ErrorGatewayTimeout:
return "Downstream gateway timed out"
default:
return "Unknown error"
}
}
// IsClientError checks if this is a client error (4xx)
func (e UCXLErrorCode) IsClientError() bool {
status := e.HTTPStatus()
return status >= 400 && status < 500
}
// IsServerError checks if this is a server error (5xx)
func (e UCXLErrorCode) IsServerError() bool {
status := e.HTTPStatus()
return status >= 500 && status < 600
}
// ShouldRetry checks if this error should trigger a retry
func (e UCXLErrorCode) ShouldRetry() bool {
switch e {
case ErrorRateLimit, ErrorInternalError, ErrorServiceUnavailable, ErrorGatewayTimeout:
return true
default:
return false
}
}
// HTTPStatus returns the HTTP status code for the response code
func (r UCXLResponseCode) HTTPStatus() int {
switch r {
case ResponseOK:
return 200
case ResponseCreated:
return 201
case ResponseAccepted:
return 202
case ResponseNoContent:
return 204
case ResponsePartialContent:
return 206
case ResponseNotModified:
return 304
default:
return 200
}
}
// DefaultMessage returns the default success message for this code
func (r UCXLResponseCode) DefaultMessage() string {
switch r {
case ResponseOK:
return "Request completed successfully"
case ResponseCreated:
return "Resource created successfully"
case ResponseAccepted:
return "Request accepted for processing"
case ResponseNoContent:
return "Request completed with no content to return"
case ResponsePartialContent:
return "Partial results returned"
case ResponseNotModified:
return "Resource not modified since last fetch"
default:
return "Success"
}
}
// IsAsync checks if this indicates an asynchronous operation
func (r UCXLResponseCode) IsAsync() bool {
return r == ResponseAccepted
}
// IsPartial checks if this indicates partial/incomplete results
func (r UCXLResponseCode) IsPartial() bool {
return r == ResponsePartialContent || r == ResponseAccepted
}
// UCXLErrorResponse represents the standardized UCXL error response payload
type UCXLErrorResponse struct {
Error UCXLError `json:"error"`
}
// UCXLError contains the error details
type UCXLError struct {
Code UCXLErrorCode `json:"code"`
Message string `json:"message"`
Details map[string]interface{} `json:"details,omitempty"`
Source string `json:"source"`
Path string `json:"path"`
RequestID string `json:"request_id"`
Timestamp time.Time `json:"timestamp"`
Cause string `json:"cause,omitempty"`
}
// UCXLSuccessResponse represents the standardized UCXL success response payload
type UCXLSuccessResponse struct {
Response UCXLResponse `json:"response"`
}
// UCXLResponse contains the response details
type UCXLResponse struct {
Code UCXLResponseCode `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
Details map[string]interface{} `json:"details,omitempty"`
RequestID string `json:"request_id"`
Timestamp time.Time `json:"timestamp"`
}
// ErrorBuilder helps build standardized error responses
type ErrorBuilder struct {
code UCXLErrorCode
message string
details map[string]interface{}
source string
path string
requestID string
cause string
}
// NewErrorBuilder creates a new error builder with the specified code
func NewErrorBuilder(code UCXLErrorCode) *ErrorBuilder {
return &ErrorBuilder{
code: code,
details: make(map[string]interface{}),
source: "ucxl-api/v1",
path: "/",
requestID: fmt.Sprintf("req-%s", uuid.New().String()[:8]),
}
}
// Message sets a custom error message
func (b *ErrorBuilder) Message(message string) *ErrorBuilder {
b.message = message
return b
}
// Field adds details about the field that failed
func (b *ErrorBuilder) Field(field string, provided interface{}) *ErrorBuilder {
b.details["field"] = field
b.details["provided"] = provided
return b
}
// ExpectedFormat adds expected format information
func (b *ErrorBuilder) ExpectedFormat(format string) *ErrorBuilder {
b.details["expected_format"] = format
return b
}
// Detail adds a detail field
func (b *ErrorBuilder) Detail(key string, value interface{}) *ErrorBuilder {
b.details[key] = value
return b
}
// Source sets the source service
func (b *ErrorBuilder) Source(source string) *ErrorBuilder {
b.source = source
return b
}
// Path sets the request path
func (b *ErrorBuilder) Path(path string) *ErrorBuilder {
b.path = path
return b
}
// RequestID sets the request ID
func (b *ErrorBuilder) RequestID(requestID string) *ErrorBuilder {
b.requestID = requestID
return b
}
// Cause sets the error cause
func (b *ErrorBuilder) Cause(cause string) *ErrorBuilder {
b.cause = cause
return b
}
// Build creates the error response
func (b *ErrorBuilder) Build() *UCXLErrorResponse {
message := b.message
if message == "" {
message = b.code.DefaultMessage()
}
var details map[string]interface{}
if len(b.details) > 0 {
details = b.details
}
return &UCXLErrorResponse{
Error: UCXLError{
Code: b.code,
Message: message,
Details: details,
Source: b.source,
Path: b.path,
RequestID: b.requestID,
Timestamp: time.Now().UTC(),
Cause: b.cause,
},
}
}
// ResponseBuilder helps build standardized success responses
type ResponseBuilder struct {
code UCXLResponseCode
message string
data interface{}
details map[string]interface{}
requestID string
}
// NewResponseBuilder creates a new response builder with the specified code
func NewResponseBuilder(code UCXLResponseCode) *ResponseBuilder {
return &ResponseBuilder{
code: code,
details: make(map[string]interface{}),
requestID: fmt.Sprintf("req-%s", uuid.New().String()[:8]),
}
}
// Message sets a custom success message
func (b *ResponseBuilder) Message(message string) *ResponseBuilder {
b.message = message
return b
}
// Data sets the response data
func (b *ResponseBuilder) Data(data interface{}) *ResponseBuilder {
b.data = data
return b
}
// Detail adds a detail field
func (b *ResponseBuilder) Detail(key string, value interface{}) *ResponseBuilder {
b.details[key] = value
return b
}
// RequestID sets the request ID
func (b *ResponseBuilder) RequestID(requestID string) *ResponseBuilder {
b.requestID = requestID
return b
}
// Build creates the success response
func (b *ResponseBuilder) Build() *UCXLSuccessResponse {
message := b.message
if message == "" {
message = b.code.DefaultMessage()
}
var details map[string]interface{}
if len(b.details) > 0 {
details = b.details
}
return &UCXLSuccessResponse{
Response: UCXLResponse{
Code: b.code,
Message: message,
Data: b.data,
Details: details,
RequestID: b.requestID,
Timestamp: time.Now().UTC(),
},
}
}
// JSON marshaling helpers
// ToJSON converts the error response to JSON
func (e *UCXLErrorResponse) ToJSON() ([]byte, error) {
return json.Marshal(e)
}
// FromJSON creates an error response from JSON
func (e *UCXLErrorResponse) FromJSON(data []byte) error {
return json.Unmarshal(data, e)
}
// ToJSON converts the success response to JSON
func (r *UCXLSuccessResponse) ToJSON() ([]byte, error) {
return json.Marshal(r)
}
// FromJSON creates a success response from JSON
func (r *UCXLSuccessResponse) FromJSON(data []byte) error {
return json.Unmarshal(data, r)
}