errors.go
go
package friendli
import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)
// APIError represents an error returned by the Friendli API
type APIError struct {
	StatusCode int
	Message    string
	Type       string
	Details    map[string]interface{}
}
// Error implements the error interface
func (e *APIError) Error() string {
	if e.Type != "" {
		return fmt.Sprintf("friendli: %s (status %d): %s", e.Type, e.StatusCode, e.Message)
	}
	return fmt.Sprintf("friendli: status %d: %s", e.StatusCode, e.Message)
}
// IsRateLimitError returns true if the error is a rate limit error
func (e *APIError) IsRateLimitError() bool {
	return e.StatusCode == http.StatusTooManyRequests
}
// IsAuthenticationError returns true if the error is an authentication error
func (e *APIError) IsAuthenticationError() bool {
	return e.StatusCode == http.StatusUnauthorized
}
// IsValidationError returns true if the error is a validation error
func (e *APIError) IsValidationError() bool {
	return e.StatusCode == http.StatusUnprocessableEntity
}
// errorResponse represents the structure of error responses from the API
type errorResponse struct {
	Error struct {
		Message string                 `json:"message"`
		Type    string                 `json:"type"`
		Code    string                 `json:"code"`
		Param   string                 `json:"param"`
		Details map[string]interface{} `json:"details"`
	} `json:"error"`
}
// parseErrorResponse attempts to parse an error response from the API
func parseErrorResponse(resp *http.Response) error {
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return &APIError{
			StatusCode: resp.StatusCode,
			Message:    fmt.Sprintf("failed to read error response: %v", err),
		}
	}
	var errResp errorResponse
	if err := json.Unmarshal(body, &errResp); err != nil {
		// If we can't parse the error response, return a generic error with the body
		return &APIError{
			StatusCode: resp.StatusCode,
			Message:    string(body),
		}
	}
	return &APIError{
		StatusCode: resp.StatusCode,
		Message:    errResp.Error.Message,
		Type:       errResp.Error.Type,
		Details:    errResp.Error.Details,
	}
}
// ValidationError represents a validation error for request parameters
type ValidationError struct {
	Field   string
	Message string
}
// Error implements the error interface
func (e *ValidationError) Error() string {
	return fmt.Sprintf("validation error: %s: %s", e.Field, e.Message)
}
// Common validation errors
// ErrMissingAPIKey is returned when the API key is not provided
var ErrMissingAPIKey = &ValidationError{
	Field:   "apiKey",
	Message: "API key is required",
}
// ErrMissingModel is returned when the model is not specified
var ErrMissingModel = &ValidationError{
	Field:   "model",
	Message: "model is required",
}
// ErrEmptyMessages is returned when the messages array is empty
var ErrEmptyMessages = &ValidationError{
	Field:   "messages",
	Message: "at least one message is required",
}
No comments yet.