1package fantasy
2
3import (
4 "encoding/json"
5 "errors"
6 "fmt"
7)
8
9// AIError is a custom error type for AI SDK related errors.
10type AIError struct {
11 Message string
12 Cause error
13}
14
15// Error implements the error interface.
16func (e *AIError) Error() string {
17 return e.Message
18}
19
20// Unwrap returns the underlying cause of the error.
21func (e *AIError) Unwrap() error {
22 return e.Cause
23}
24
25// NewAIError creates a new AI SDK Error.
26func NewAIError(message string, cause error) *AIError {
27 return &AIError{
28 Message: message,
29 Cause: cause,
30 }
31}
32
33// IsAIError checks if the given error is an AI SDK Error.
34func IsAIError(err error) bool {
35 var sdkErr *AIError
36 return errors.As(err, &sdkErr)
37}
38
39// APICallError represents an error from an API call.
40type APICallError struct {
41 *AIError
42 URL string
43 RequestDump string
44 StatusCode int
45 ResponseHeaders map[string]string
46 ResponseDump string
47 IsRetryable bool
48}
49
50// NewAPICallError creates a new API call error.
51func NewAPICallError(message, url string, requestDump string, statusCode int, responseHeaders map[string]string, responseDump string, cause error, isRetryable bool) *APICallError {
52 if !isRetryable && statusCode != 0 {
53 isRetryable = statusCode == 408 || statusCode == 409 || statusCode == 429 || statusCode >= 500
54 }
55
56 return &APICallError{
57 AIError: NewAIError(message, cause),
58 URL: url,
59 RequestDump: requestDump,
60 StatusCode: statusCode,
61 ResponseHeaders: responseHeaders,
62 ResponseDump: responseDump,
63 IsRetryable: isRetryable,
64 }
65}
66
67// InvalidArgumentError represents an invalid function argument error.
68type InvalidArgumentError struct {
69 *AIError
70 Argument string
71}
72
73// NewInvalidArgumentError creates a new invalid argument error.
74func NewInvalidArgumentError(argument, message string, cause error) *InvalidArgumentError {
75 return &InvalidArgumentError{
76 AIError: NewAIError(message, cause),
77 Argument: argument,
78 }
79}
80
81// InvalidPromptError represents an invalid prompt error.
82type InvalidPromptError struct {
83 *AIError
84 Prompt any
85}
86
87// NewInvalidPromptError creates a new invalid prompt error.
88func NewInvalidPromptError(prompt any, message string, cause error) *InvalidPromptError {
89 return &InvalidPromptError{
90 AIError: NewAIError(fmt.Sprintf("Invalid prompt: %s", message), cause),
91 Prompt: prompt,
92 }
93}
94
95// InvalidResponseDataError represents invalid response data from the server.
96type InvalidResponseDataError struct {
97 *AIError
98 Data any
99}
100
101// NewInvalidResponseDataError creates a new invalid response data error.
102func NewInvalidResponseDataError(data any, message string) *InvalidResponseDataError {
103 if message == "" {
104 dataJSON, _ := json.Marshal(data)
105 message = fmt.Sprintf("Invalid response data: %s.", string(dataJSON))
106 }
107 return &InvalidResponseDataError{
108 AIError: NewAIError(message, nil),
109 Data: data,
110 }
111}
112
113// UnsupportedFunctionalityError represents an unsupported functionality error.
114type UnsupportedFunctionalityError struct {
115 *AIError
116 Functionality string
117}
118
119// NewUnsupportedFunctionalityError creates a new unsupported functionality error.
120func NewUnsupportedFunctionalityError(functionality, message string) *UnsupportedFunctionalityError {
121 if message == "" {
122 message = fmt.Sprintf("'%s' functionality not supported.", functionality)
123 }
124 return &UnsupportedFunctionalityError{
125 AIError: NewAIError(message, nil),
126 Functionality: functionality,
127 }
128}