package hcfs import ( "fmt" "time" ) // Error types for HCFS Go SDK // APIError represents a generic API error type APIError struct { Message string `json:"message"` StatusCode int `json:"status_code,omitempty"` } func (e *APIError) Error() string { if e.StatusCode > 0 { return fmt.Sprintf("API error (HTTP %d): %s", e.StatusCode, e.Message) } return fmt.Sprintf("API error: %s", e.Message) } // ValidationError represents a request validation error type ValidationError struct { Message string `json:"message"` Details []ValidationErrorDetail `json:"details,omitempty"` } type ValidationErrorDetail struct { Field string `json:"field,omitempty"` Message string `json:"message"` Code string `json:"code,omitempty"` } func (e *ValidationError) Error() string { if len(e.Details) > 0 { return fmt.Sprintf("Validation error: %s (%d validation issues)", e.Message, len(e.Details)) } return fmt.Sprintf("Validation error: %s", e.Message) } // AuthenticationError represents an authentication failure type AuthenticationError struct { Message string `json:"message"` } func (e *AuthenticationError) Error() string { return fmt.Sprintf("Authentication error: %s", e.Message) } // AuthorizationError represents an authorization failure type AuthorizationError struct { Message string `json:"message"` } func (e *AuthorizationError) Error() string { return fmt.Sprintf("Authorization error: %s", e.Message) } // NotFoundError represents a resource not found error type NotFoundError struct { Message string `json:"message"` } func (e *NotFoundError) Error() string { return fmt.Sprintf("Not found: %s", e.Message) } // RateLimitError represents a rate limiting error type RateLimitError struct { Message string `json:"message"` RetryAfter string `json:"retry_after,omitempty"` } func (e *RateLimitError) Error() string { if e.RetryAfter != "" { return fmt.Sprintf("Rate limit exceeded: %s (retry after %s)", e.Message, e.RetryAfter) } return fmt.Sprintf("Rate limit exceeded: %s", e.Message) } // ServerError represents a server-side error type ServerError struct { Message string `json:"message"` StatusCode int `json:"status_code"` } func (e *ServerError) Error() string { return fmt.Sprintf("Server error (HTTP %d): %s", e.StatusCode, e.Message) } // ConnectionError represents a network connection error type ConnectionError struct { Message string `json:"message"` Cause error `json:"cause,omitempty"` } func (e *ConnectionError) Error() string { if e.Cause != nil { return fmt.Sprintf("Connection error: %s (caused by: %v)", e.Message, e.Cause) } return fmt.Sprintf("Connection error: %s", e.Message) } // TimeoutError represents a timeout error type TimeoutError struct { Message string `json:"message"` Timeout time.Duration `json:"timeout,omitempty"` } func (e *TimeoutError) Error() string { if e.Timeout > 0 { return fmt.Sprintf("Timeout error: %s (timeout: %v)", e.Message, e.Timeout) } return fmt.Sprintf("Timeout error: %s", e.Message) } // CacheError represents a cache operation error type CacheError struct { Message string `json:"message"` Cause error `json:"cause,omitempty"` } func (e *CacheError) Error() string { if e.Cause != nil { return fmt.Sprintf("Cache error: %s (caused by: %v)", e.Message, e.Cause) } return fmt.Sprintf("Cache error: %s", e.Message) } // BatchError represents a batch operation error type BatchError struct { Message string `json:"message"` FailedItems []map[string]interface{} `json:"failed_items,omitempty"` } func (e *BatchError) Error() string { if len(e.FailedItems) > 0 { return fmt.Sprintf("Batch error: %s (%d failed items)", e.Message, len(e.FailedItems)) } return fmt.Sprintf("Batch error: %s", e.Message) } // SearchError represents a search operation error type SearchError struct { Message string `json:"message"` Query string `json:"query,omitempty"` SearchType string `json:"search_type,omitempty"` } func (e *SearchError) Error() string { parts := []string{"Search error", e.Message} if e.SearchType != "" { parts = append(parts, fmt.Sprintf("(type: %s)", e.SearchType)) } if e.Query != "" { parts = append(parts, fmt.Sprintf("(query: '%s')", e.Query)) } result := parts[0] + ": " + parts[1] if len(parts) > 2 { for i := 2; i < len(parts); i++ { result += " " + parts[i] } } return result } // StreamError represents a WebSocket/streaming error type StreamError struct { Message string `json:"message"` Cause error `json:"cause,omitempty"` } func (e *StreamError) Error() string { if e.Cause != nil { return fmt.Sprintf("Stream error: %s (caused by: %v)", e.Message, e.Cause) } return fmt.Sprintf("Stream error: %s", e.Message) } // IsRetryable checks if an error should trigger a retry func IsRetryable(err error) bool { switch err.(type) { case *RateLimitError, *ServerError, *TimeoutError, *ConnectionError: return true case *APIError: apiErr := err.(*APIError) return apiErr.StatusCode >= 500 || apiErr.StatusCode == 429 default: return false } } // IsTemporary checks if an error is temporary func IsTemporary(err error) bool { switch err.(type) { case *RateLimitError, *TimeoutError, *ConnectionError: return true case *ServerError: serverErr := err.(*ServerError) return serverErr.StatusCode == 502 || serverErr.StatusCode == 503 || serverErr.StatusCode == 504 default: return false } }