Commit
Handle key management failures
commit
fb73e0f
1 changed file with +20 and −5
modified src/components/api-key-dialog.tsx +20 −5
| @@ -39,11 +39,15 @@export function ApiKeyDialog({ | ||
| 39 | 39 | const [busy, setBusy] = useState(false); |
| 40 | 40 | |
| 41 | 41 | const refresh = useCallback(async () => { |
| 42 | - const res = await fetch('/api/keys'); | |
| 43 | - if (res.ok) { | |
| 42 | + try { | |
| 43 | + const res = await fetch('/api/keys'); | |
| 44 | + if (!res.ok) return false; | |
| 44 | 45 | const s = (await res.json()) as KeyStatus; |
| 45 | 46 | setStatus(s); |
| 46 | 47 | setMode(s.authenticated ? 'save' : 'session'); |
| 48 | + return true; | |
| 49 | + } catch { | |
| 50 | + return false; | |
| 47 | 51 | } |
| 48 | 52 | }, []); |
| 49 | 53 | |
| @@ -77,6 +81,8 @@export function ApiKeyDialog({ | ||
| 77 | 81 | setApiKey(''); |
| 78 | 82 | await refresh(); |
| 79 | 83 | onChanged?.(); |
| 84 | + } catch { | |
| 85 | + toast.error('Could not connect models'); | |
| 80 | 86 | } finally { |
| 81 | 87 | setBusy(false); |
| 82 | 88 | } |
| @@ -85,10 +91,13 @@export function ApiKeyDialog({ | ||
| 85 | 91 | const remove = async () => { |
| 86 | 92 | setBusy(true); |
| 87 | 93 | try { |
| 88 | - await fetch('/api/keys', { method: 'DELETE' }); | |
| 94 | + const res = await fetch('/api/keys', { method: 'DELETE' }); | |
| 95 | + if (!res.ok) throw new Error('Key removal failed'); | |
| 89 | 96 | toast.success('Key removed'); |
| 90 | 97 | await refresh(); |
| 91 | 98 | onChanged?.(); |
| 99 | + } catch { | |
| 100 | + toast.error('Could not remove key'); | |
| 92 | 101 | } finally { |
| 93 | 102 | setBusy(false); |
| 94 | 103 | } |
| @@ -119,11 +128,17 @@export function ApiKeyDialog({ | ||
| 119 | 128 | </div> |
| 120 | 129 | ) : ( |
| 121 | 130 | <div className="space-y-4"> |
| 122 | - {status?.saved && ( | |
| 131 | + {status?.hasKey && status.source !== 'mock' && ( | |
| 123 | 132 | <div className="flex items-center justify-between rounded-lg border bg-secondary/40 px-3 py-2 text-sm"> |
| 124 | 133 | <span className="flex items-center gap-2"> |
| 125 | 134 | <ShieldCheck className="h-4 w-4 text-emerald-500" /> |
| 126 | - Saved key <code className="font-mono text-xs">{status.saved.keyMask}</code> | |
| 135 | + {status.source === 'saved' && status.saved ? ( | |
| 136 | + <> | |
| 137 | + Saved key <code className="font-mono text-xs">{status.saved.keyMask}</code> | |
| 138 | + </> | |
| 139 | + ) : ( | |
| 140 | + 'Session key connected' | |
| 141 | + )} | |
| 127 | 142 | </span> |
| 128 | 143 | <Button size="sm" variant="ghost" onClick={remove} disabled={busy}> |
| 129 | 144 | <Trash2 className="h-3.5 w-3.5" /> Remove |