refine(usage): enhance query robustness and error handling
Backend improvements:
- Add InvalidHttpMethod error enum for better error semantics
- Clamp HTTP timeout to 2-30s to prevent config abuse
- Strict HTTP method validation instead of silent fallback to GET
Frontend improvements:
- Add i18n support for usage query errors (en/zh)
- Improve error handling with type-safe unknown instead of any
- Optimize i18n import (direct import instead of dynamic)
- Disable auto-retry for usage queries to avoid API stampede
Additional changes:
- Apply prettier formatting to affected files
Files changed:
- src-tauri/src/error.rs (+2)
- src-tauri/src/usage_script.rs (+8 -2)
- src/i18n/locales/{en,zh}.json (+4 -1 each)
- src/lib/api/usage.ts (+21 -4)
- src/lib/query/queries.ts (+1)
- style: prettier formatting on 6 other files
This commit is contained in:
@@ -166,7 +166,9 @@ export function ClaudeFormFields({
|
||||
id="claudeModel"
|
||||
type="text"
|
||||
value={claudeModel}
|
||||
onChange={(e) => onModelChange("ANTHROPIC_MODEL", e.target.value)}
|
||||
onChange={(e) =>
|
||||
onModelChange("ANTHROPIC_MODEL", e.target.value)
|
||||
}
|
||||
placeholder={t("providerForm.modelPlaceholder", {
|
||||
defaultValue: "claude-3-7-sonnet-20250219",
|
||||
})}
|
||||
@@ -177,7 +179,9 @@ export function ClaudeFormFields({
|
||||
{/* 默认 Haiku */}
|
||||
<div className="space-y-2">
|
||||
<FormLabel htmlFor="claudeDefaultHaikuModel">
|
||||
{t("providerForm.anthropicDefaultHaikuModel", { defaultValue: "Haiku 默认模型" })}
|
||||
{t("providerForm.anthropicDefaultHaikuModel", {
|
||||
defaultValue: "Haiku 默认模型",
|
||||
})}
|
||||
</FormLabel>
|
||||
<Input
|
||||
id="claudeDefaultHaikuModel"
|
||||
@@ -196,14 +200,19 @@ export function ClaudeFormFields({
|
||||
{/* 默认 Sonnet */}
|
||||
<div className="space-y-2">
|
||||
<FormLabel htmlFor="claudeDefaultSonnetModel">
|
||||
{t("providerForm.anthropicDefaultSonnetModel", { defaultValue: "Sonnet 默认模型" })}
|
||||
{t("providerForm.anthropicDefaultSonnetModel", {
|
||||
defaultValue: "Sonnet 默认模型",
|
||||
})}
|
||||
</FormLabel>
|
||||
<Input
|
||||
id="claudeDefaultSonnetModel"
|
||||
type="text"
|
||||
value={defaultSonnetModel}
|
||||
onChange={(e) =>
|
||||
onModelChange("ANTHROPIC_DEFAULT_SONNET_MODEL", e.target.value)
|
||||
onModelChange(
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL",
|
||||
e.target.value,
|
||||
)
|
||||
}
|
||||
placeholder={t("providerForm.modelPlaceholder", {
|
||||
defaultValue: "claude-3-7-sonnet-20250219",
|
||||
@@ -215,7 +224,9 @@ export function ClaudeFormFields({
|
||||
{/* 默认 Opus */}
|
||||
<div className="space-y-2">
|
||||
<FormLabel htmlFor="claudeDefaultOpusModel">
|
||||
{t("providerForm.anthropicDefaultOpusModel", { defaultValue: "Opus 默认模型" })}
|
||||
{t("providerForm.anthropicDefaultOpusModel", {
|
||||
defaultValue: "Opus 默认模型",
|
||||
})}
|
||||
</FormLabel>
|
||||
<Input
|
||||
id="claudeDefaultOpusModel"
|
||||
@@ -233,7 +244,8 @@ export function ClaudeFormFields({
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("providerForm.modelHelper", {
|
||||
defaultValue: "可选:指定默认使用的 Claude 模型,留空则使用系统默认。",
|
||||
defaultValue:
|
||||
"可选:指定默认使用的 Claude 模型,留空则使用系统默认。",
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,10 @@ import { Form } from "@/components/ui/form";
|
||||
import { providerSchema, type ProviderFormData } from "@/lib/schemas/provider";
|
||||
import type { AppId } from "@/lib/api";
|
||||
import type { ProviderCategory, ProviderMeta } from "@/types";
|
||||
import { providerPresets, type ProviderPreset } from "@/config/claudeProviderPresets";
|
||||
import {
|
||||
providerPresets,
|
||||
type ProviderPreset,
|
||||
} from "@/config/claudeProviderPresets";
|
||||
import {
|
||||
codexProviderPresets,
|
||||
type CodexProviderPreset,
|
||||
|
||||
@@ -9,7 +9,10 @@ interface UseModelStateProps {
|
||||
* 管理模型选择状态
|
||||
* 支持 ANTHROPIC_MODEL 和 ANTHROPIC_SMALL_FAST_MODEL
|
||||
*/
|
||||
export function useModelState({ settingsConfig, onConfigChange }: UseModelStateProps) {
|
||||
export function useModelState({
|
||||
settingsConfig,
|
||||
onConfigChange,
|
||||
}: UseModelStateProps) {
|
||||
const [claudeModel, setClaudeModel] = useState("");
|
||||
const [defaultHaikuModel, setDefaultHaikuModel] = useState("");
|
||||
const [defaultSonnetModel, setDefaultSonnetModel] = useState("");
|
||||
@@ -24,9 +27,12 @@ export function useModelState({ settingsConfig, onConfigChange }: UseModelStateP
|
||||
try {
|
||||
const cfg = settingsConfig ? JSON.parse(settingsConfig) : {};
|
||||
const env = cfg?.env || {};
|
||||
const model = typeof env.ANTHROPIC_MODEL === "string" ? env.ANTHROPIC_MODEL : "";
|
||||
const model =
|
||||
typeof env.ANTHROPIC_MODEL === "string" ? env.ANTHROPIC_MODEL : "";
|
||||
const small =
|
||||
typeof env.ANTHROPIC_SMALL_FAST_MODEL === "string" ? env.ANTHROPIC_SMALL_FAST_MODEL : "";
|
||||
typeof env.ANTHROPIC_SMALL_FAST_MODEL === "string"
|
||||
? env.ANTHROPIC_SMALL_FAST_MODEL
|
||||
: "";
|
||||
const haiku =
|
||||
typeof env.ANTHROPIC_DEFAULT_HAIKU_MODEL === "string"
|
||||
? env.ANTHROPIC_DEFAULT_HAIKU_MODEL
|
||||
@@ -59,12 +65,16 @@ export function useModelState({ settingsConfig, onConfigChange }: UseModelStateP
|
||||
value: string,
|
||||
) => {
|
||||
if (field === "ANTHROPIC_MODEL") setClaudeModel(value);
|
||||
if (field === "ANTHROPIC_DEFAULT_HAIKU_MODEL") setDefaultHaikuModel(value);
|
||||
if (field === "ANTHROPIC_DEFAULT_SONNET_MODEL") setDefaultSonnetModel(value);
|
||||
if (field === "ANTHROPIC_DEFAULT_HAIKU_MODEL")
|
||||
setDefaultHaikuModel(value);
|
||||
if (field === "ANTHROPIC_DEFAULT_SONNET_MODEL")
|
||||
setDefaultSonnetModel(value);
|
||||
if (field === "ANTHROPIC_DEFAULT_OPUS_MODEL") setDefaultOpusModel(value);
|
||||
|
||||
try {
|
||||
const currentConfig = settingsConfig ? JSON.parse(settingsConfig) : { env: {} };
|
||||
const currentConfig = settingsConfig
|
||||
? JSON.parse(settingsConfig)
|
||||
: { env: {} };
|
||||
if (!currentConfig.env) currentConfig.env = {};
|
||||
|
||||
// 新键仅写入;旧键不再写入
|
||||
|
||||
Reference in New Issue
Block a user