mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-16 23:41:43 +00:00
fix(ui): surface a visible error when default_litellm_params JSON is invalid
Invalid JSON typed into the Default LiteLLM Params textarea was silently swallowed on blur (console.error only, no on-screen indication), so an admin could think their edit was saved when it was actually discarded. Now flags the field with an error state and shows a warning notification, and clears both once the field is edited again.
This commit is contained in:
parent
f6d67f025d
commit
221183b2f4
2 changed files with 29 additions and 3 deletions
|
|
@ -78,7 +78,7 @@ describe("DefaultLitellmParamsSection", () => {
|
|||
expect(onChange).toHaveBeenCalledWith({ timeout: 60, cache_control_injection_points: [{ location: "message" }] });
|
||||
});
|
||||
|
||||
it("should not call onChange with invalid JSON left in the textarea on blur", async () => {
|
||||
it("should not call onChange and should flag the field as invalid when the textarea has invalid JSON on blur", async () => {
|
||||
const onChange = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
render(<DefaultLitellmParamsSection value={{ timeout: 30 }} routerFieldsMetadata={{}} onChange={onChange} />);
|
||||
|
|
@ -89,5 +89,23 @@ describe("DefaultLitellmParamsSection", () => {
|
|||
await user.tab();
|
||||
|
||||
expect(onChange).not.toHaveBeenCalled();
|
||||
expect(textarea).toHaveClass("ant-input-status-error");
|
||||
});
|
||||
|
||||
it("should clear the invalid state once the textarea is edited again", async () => {
|
||||
const onChange = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
render(<DefaultLitellmParamsSection value={{ timeout: 30 }} routerFieldsMetadata={{}} onChange={onChange} />);
|
||||
|
||||
const textarea = screen.getByRole("textbox") as HTMLTextAreaElement;
|
||||
await user.clear(textarea);
|
||||
await user.type(textarea, "not json");
|
||||
await user.tab();
|
||||
expect(textarea).toHaveClass("ant-input-status-error");
|
||||
|
||||
await user.click(textarea);
|
||||
await user.type(textarea, "{{}}");
|
||||
|
||||
expect(textarea).not.toHaveClass("ant-input-status-error");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Input, Switch } from "antd";
|
|||
import CacheControlInjectionPointsEditor, {
|
||||
CacheControlInjectionPoint,
|
||||
} from "../shared/cache_control_injection_points_editor";
|
||||
import NotificationsManager from "../molecules/notifications_manager";
|
||||
|
||||
interface DefaultLitellmParamsSectionProps {
|
||||
value: { [key: string]: any };
|
||||
|
|
@ -20,6 +21,7 @@ const DefaultLitellmParamsSection: React.FC<DefaultLitellmParamsSectionProps> =
|
|||
|
||||
const [otherParamsText, setOtherParamsText] = React.useState(() => JSON.stringify(otherParams, null, 2));
|
||||
const [showCacheControl, setShowCacheControl] = React.useState((cache_control_injection_points?.length ?? 0) > 0);
|
||||
const [hasInvalidJson, setHasInvalidJson] = React.useState(false);
|
||||
|
||||
const parseOtherParams = (): { [key: string]: any } => {
|
||||
try {
|
||||
|
|
@ -32,9 +34,11 @@ const DefaultLitellmParamsSection: React.FC<DefaultLitellmParamsSectionProps> =
|
|||
const handleOtherParamsBlur = () => {
|
||||
try {
|
||||
const parsed = JSON.parse(otherParamsText || "{}");
|
||||
setHasInvalidJson(false);
|
||||
onChange({ ...parsed, cache_control_injection_points });
|
||||
} catch (error) {
|
||||
console.error("Error parsing default_litellm_params JSON:", error);
|
||||
setHasInvalidJson(true);
|
||||
NotificationsManager.warning(`Default LiteLLM Params is not valid JSON, change not saved: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -57,8 +61,12 @@ const DefaultLitellmParamsSection: React.FC<DefaultLitellmParamsSectionProps> =
|
|||
<p className="text-xs text-gray-500 mt-0.5 mb-2">{meta?.field_description || ""}</p>
|
||||
<Input.TextArea
|
||||
value={otherParamsText}
|
||||
onChange={(e) => setOtherParamsText(e.target.value)}
|
||||
onChange={(e) => {
|
||||
setOtherParamsText(e.target.value);
|
||||
setHasInvalidJson(false);
|
||||
}}
|
||||
onBlur={handleOtherParamsBlur}
|
||||
status={hasInvalidJson ? "error" : undefined}
|
||||
autoSize={{ minRows: 2 }}
|
||||
className="font-mono text-sm w-full"
|
||||
/>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue