Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: void provider's errors are sent directly to the end user #889

Merged
merged 2 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions pkg/bridge/ai/api_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@

caller, err := service.LoadOrCreateCaller(r)
if err != nil {
RespondWithError(w, http.StatusBadRequest, err)
RespondWithError(w, http.StatusBadRequest, err, logger)

Check warning on line 114 in pkg/bridge/ai/api_server.go

View check run for this annotation

Codecov / codecov/patch

pkg/bridge/ai/api_server.go#L114

Added line #L114 was not covered by tests
return
}
ctx = WithCallerContext(ctx, caller)
Expand Down Expand Up @@ -146,7 +146,7 @@

tcs, err := register.ListToolCalls(FromCallerContext(r.Context()).Metadata())
if err != nil {
RespondWithError(w, http.StatusInternalServerError, err)
RespondWithError(w, http.StatusInternalServerError, err, h.service.logger)

Check warning on line 149 in pkg/bridge/ai/api_server.go

View check run for this annotation

Codecov / codecov/patch

pkg/bridge/ai/api_server.go#L149

Added line #L149 was not covered by tests
return
}

Expand All @@ -169,7 +169,7 @@
)
defer r.Body.Close()

req, err := DecodeRequest[ai.InvokeRequest](r, w)
req, err := DecodeRequest[ai.InvokeRequest](r, w, h.service.logger)
if err != nil {
return
}
Expand All @@ -181,7 +181,7 @@

res, err := h.service.GetInvoke(ctx, req.Prompt, baseSystemMessage, transID, FromCallerContext(ctx), req.IncludeCallStack)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, err)
RespondWithError(w, http.StatusInternalServerError, err, h.service.logger)

Check warning on line 184 in pkg/bridge/ai/api_server.go

View check run for this annotation

Codecov / codecov/patch

pkg/bridge/ai/api_server.go#L184

Added line #L184 was not covered by tests
return
}

Expand All @@ -197,7 +197,7 @@
)
defer r.Body.Close()

req, err := DecodeRequest[openai.ChatCompletionRequest](r, w)
req, err := DecodeRequest[openai.ChatCompletionRequest](r, w, h.service.logger)
if err != nil {
return
}
Expand All @@ -206,28 +206,39 @@
defer cancel()

if err := h.service.GetChatCompletions(ctx, req, transID, FromCallerContext(ctx), w); err != nil {
RespondWithError(w, http.StatusBadRequest, err)
RespondWithError(w, http.StatusBadRequest, err, h.service.logger)

Check warning on line 209 in pkg/bridge/ai/api_server.go

View check run for this annotation

Codecov / codecov/patch

pkg/bridge/ai/api_server.go#L209

Added line #L209 was not covered by tests
return
}
}

// DecodeRequest decodes the request body into given type.
func DecodeRequest[T any](r *http.Request, w http.ResponseWriter) (T, error) {
func DecodeRequest[T any](r *http.Request, w http.ResponseWriter, logger *slog.Logger) (T, error) {
var req T
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
w.Header().Set("Content-Type", "application/json")
RespondWithError(w, http.StatusBadRequest, err)
RespondWithError(w, http.StatusBadRequest, err, logger)
return req, err
}

return req, nil
}

// RespondWithError writes an error to response according to the OpenAI API spec.
func RespondWithError(w http.ResponseWriter, code int, err error) {
func RespondWithError(w http.ResponseWriter, code int, err error, logger *slog.Logger) {
logger.Error("bridge server error", "error", err)

errString := err.Error()
oerr, ok := err.(*openai.APIError)
if ok {
if oerr.HTTPStatusCode >= 400 {
code = http.StatusInternalServerError
errString = "Internal Server Error, Please Try Again Later."

Check warning on line 236 in pkg/bridge/ai/api_server.go

View check run for this annotation

Codecov / codecov/patch

pkg/bridge/ai/api_server.go#L234-L236

Added lines #L234 - L236 were not covered by tests
}
}

w.WriteHeader(code)
w.Write([]byte(fmt.Sprintf(`{"error":{"code":"%d","message":"%s"}}`, code, err.Error())))
w.Write([]byte(fmt.Sprintf(`{"error":{"code":"%d","message":"%s"}}`, code, errString)))
}

func getLocalIP() (string, error) {
Expand Down
10 changes: 5 additions & 5 deletions pkg/bridge/ai/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,15 @@ func (srv *Service) GetChatCompletions(ctx context.Context, req openai.ChatCompl
// 4. request first chat for getting tools
if req.Stream {
_, firstCallSpan := srv.option.Tracer.Start(reqCtx, "first_call_request")
var (
flusher = eventFlusher(w)
isFunctionCall = false
)

resStream, err := srv.provider.GetChatCompletionsStream(reqCtx, req, md)
if err != nil {
return err
}

var (
flusher = eventFlusher(w)
isFunctionCall = false
)
var (
i int // number of chunks
j int // number of tool call chunks
Expand Down