Skip to content

Commit 5590851

Browse files
authored
fix(handler.go, chat.go): http 429 (#50)
* fix(chat.go): http 429 * fix(chat.go): http 429 * fix(chat.go): http 429 * fix(chat.go): http 429 * fix(chat.go, handler.go): http 429 * fix(handler.go, chat.go): http 429 * fix(handler.go, chat.go): http 429
1 parent d631c6a commit 5590851

File tree

2 files changed

+67
-24
lines changed

2 files changed

+67
-24
lines changed

api/handler.go

+55-23
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"github.com/google/generative-ai-go/genai"
1111
openai "github.com/sashabaranov/go-openai"
1212
"google.golang.org/api/option"
13+
"google.golang.org/api/googleapi"
14+
"github.com/pkg/errors"
1315

1416
"github.com/zhu327/gemini-openai-proxy/pkg/adapter"
1517
)
@@ -78,10 +80,7 @@ func ChatProxyHandler(c *gin.Context) {
7880
// Use fmt.Sscanf to extract the Bearer token
7981
_, err := fmt.Sscanf(authorizationHeader, "Bearer %s", &openaiAPIKey)
8082
if err != nil {
81-
c.JSON(http.StatusBadRequest, openai.APIError{
82-
Code: http.StatusBadRequest,
83-
Message: err.Error(),
84-
})
83+
handleGenerateContentError(c, err)
8584
return
8685
}
8786

@@ -122,11 +121,7 @@ func ChatProxyHandler(c *gin.Context) {
122121
if !req.Stream {
123122
resp, err := gemini.GenerateContent(ctx, req, messages)
124123
if err != nil {
125-
log.Printf("genai generate content error %v\n", err)
126-
c.JSON(http.StatusBadRequest, openai.APIError{
127-
Code: http.StatusBadRequest,
128-
Message: err.Error(),
129-
})
124+
handleGenerateContentError(c, err)
130125
return
131126
}
132127

@@ -136,11 +131,7 @@ func ChatProxyHandler(c *gin.Context) {
136131

137132
dataChan, err := gemini.GenerateStreamContent(ctx, req, messages)
138133
if err != nil {
139-
log.Printf("genai generate content error %v\n", err)
140-
c.JSON(http.StatusBadRequest, openai.APIError{
141-
Code: http.StatusBadRequest,
142-
Message: err.Error(),
143-
})
134+
handleGenerateContentError(c, err)
144135
return
145136
}
146137

@@ -155,6 +146,54 @@ func ChatProxyHandler(c *gin.Context) {
155146
})
156147
}
157148

149+
func handleGenerateContentError(c *gin.Context, err error) {
150+
log.Printf("genai generate content error %v\n", err)
151+
152+
// Try OpenAI API error first
153+
var openaiErr *openai.APIError
154+
if errors.As(err, &openaiErr) {
155+
156+
// Convert the code to an HTTP status code
157+
statusCode := http.StatusInternalServerError
158+
if code, ok := openaiErr.Code.(int); ok {
159+
statusCode = code
160+
}
161+
162+
c.AbortWithStatusJSON(statusCode, openaiErr)
163+
return
164+
}
165+
166+
// Try Google API error
167+
var googleErr *googleapi.Error
168+
if errors.As(err, &googleErr) {
169+
log.Printf("Handling Google API error with code: %d\n", googleErr.Code)
170+
statusCode := googleErr.Code
171+
if statusCode == http.StatusTooManyRequests {
172+
c.AbortWithStatusJSON(http.StatusTooManyRequests, openai.APIError{
173+
Code: http.StatusTooManyRequests,
174+
Message: "Rate limit exceeded",
175+
Type: "rate_limit_error",
176+
})
177+
return
178+
}
179+
180+
c.AbortWithStatusJSON(statusCode, openai.APIError{
181+
Code: statusCode,
182+
Message: googleErr.Message,
183+
Type: "server_error",
184+
})
185+
return
186+
}
187+
188+
// For all other errors
189+
log.Printf("Handling unknown error: %v\n", err)
190+
c.AbortWithStatusJSON(http.StatusInternalServerError, openai.APIError{
191+
Code: http.StatusInternalServerError,
192+
Message: err.Error(),
193+
Type: "server_error",
194+
})
195+
}
196+
158197
func setEventStreamHeaders(c *gin.Context) {
159198
c.Writer.Header().Set("Content-Type", "text/event-stream")
160199
c.Writer.Header().Set("Cache-Control", "no-cache")
@@ -171,10 +210,7 @@ func EmbeddingProxyHandler(c *gin.Context) {
171210
// Use fmt.Sscanf to extract the Bearer token
172211
_, err := fmt.Sscanf(authorizationHeader, "Bearer %s", &openaiAPIKey)
173212
if err != nil {
174-
c.JSON(http.StatusBadRequest, openai.APIError{
175-
Code: http.StatusBadRequest,
176-
Message: err.Error(),
177-
})
213+
handleGenerateContentError(c, err)
178214
return
179215
}
180216

@@ -214,11 +250,7 @@ func EmbeddingProxyHandler(c *gin.Context) {
214250

215251
resp, err := gemini.GenerateEmbedding(ctx, messages)
216252
if err != nil {
217-
log.Printf("genai generate content error %v\n", err)
218-
c.JSON(http.StatusBadRequest, openai.APIError{
219-
Code: http.StatusBadRequest,
220-
Message: err.Error(),
221-
})
253+
handleGenerateContentError(c, err)
222254
return
223255
}
224256

pkg/adapter/chat.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/google/generative-ai-go/genai"
1212
"github.com/pkg/errors"
1313
openai "github.com/sashabaranov/go-openai"
14+
"google.golang.org/api/googleapi"
1415
"google.golang.org/api/iterator"
1516

1617
"github.com/zhu327/gemini-openai-proxy/pkg/util"
@@ -46,9 +47,19 @@ func (g *GeminiAdapter) GenerateContent(
4647

4748
genaiResp, err := cs.SendMessage(ctx, messages[len(messages)-1].Parts...)
4849
if err != nil {
50+
var apiErr *googleapi.Error
51+
if errors.As(err, &apiErr) {
52+
if apiErr.Code == http.StatusTooManyRequests {
53+
return nil, errors.Wrap(&openai.APIError{
54+
Code: http.StatusTooManyRequests,
55+
Message: err.Error(),
56+
}, "genai send message error")
57+
}
58+
} else {
59+
log.Printf("Error is not of type *googleapi.Error: %v\n", err)
60+
}
4961
return nil, errors.Wrap(err, "genai send message error")
5062
}
51-
5263
openaiResp := genaiResponseToOpenaiResponse(g.model, genaiResp)
5364
return &openaiResp, nil
5465
}

0 commit comments

Comments
 (0)