writeUpstreamError marshals and writes a given error.
(w http.ResponseWriter, antErr *ResponseError)
| 487 | |
| 488 | // writeUpstreamError marshals and writes a given error. |
| 489 | func (i *interceptionBase) writeUpstreamError(w http.ResponseWriter, antErr *ResponseError) { |
| 490 | if antErr == nil { |
| 491 | return |
| 492 | } |
| 493 | |
| 494 | w.Header().Set("Content-Type", "application/json") |
| 495 | // Set Retry-After when a cooldown is configured. |
| 496 | if antErr.RetryAfter > 0 { |
| 497 | w.Header().Set("Retry-After", strconv.Itoa(int(math.Ceil(antErr.RetryAfter.Seconds())))) |
| 498 | } |
| 499 | w.WriteHeader(antErr.StatusCode) |
| 500 | |
| 501 | out, err := json.Marshal(antErr) |
| 502 | if err != nil { |
| 503 | i.logger.Warn(context.Background(), "failed to marshal upstream error", slog.Error(err), slog.F("error_payload", fmt.Sprintf("%+v", antErr))) |
| 504 | // Response has to match expected format. |
| 505 | // See https://docs.claude.com/en/api/errors#error-shapes. |
| 506 | _, _ = w.Write([]byte(fmt.Sprintf(`{ |
| 507 | "type":"error", |
| 508 | "error": { |
| 509 | "type": "error", |
| 510 | "message":"error marshaling upstream error" |
| 511 | }, |
| 512 | "request_id": "%s" |
| 513 | }`, i.ID().String()))) |
| 514 | } else { |
| 515 | _, _ = w.Write(out) |
| 516 | } |
| 517 | } |
| 518 | |
| 519 | func (i *interceptionBase) hasInjectableTools() bool { |
| 520 | return i.mcpProxy != nil && len(i.mcpProxy.ListTools()) > 0 |