mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 15:09:42 +02:00
fix(custom-model,toast): surface the real apply error, and make error toasts sticky with a close button
Two related fixes, both needed to actually diagnose 'Session started on the native backend — could not apply the custom endpoint' reports from live testing: 1. runCustomModelEntry()'s apply call went through _apiJson(), which unwraps a success body but SWALLOWS a failure response entirely and returns null — discarding the one thing (error, errorCode) that would tell 'endpoint unreachable' apart from 'not a discovered model', 'remote/Docker session', or a dozen other real causes the apply route already reports distinctly. Switched to _api() so the actual response body is read on failure too, and the toast now includes the real message. 2. showToast() defaulted every toast, error or not, to a 3s auto-dismiss with no way to read it again — exactly what made the above generic message impossible to act on even before the fix above. Error toasts now default to sticky (duration: 0, no auto-dismiss) unless a caller opts into a duration, and every toast — sticky or not — gets an explicit close (x) button, since a sticky toast with no way to dismiss it would just accumulate across repeated failures. Tests: custom-model-run-menu-ui.test.ts's two apply tests updated for the _api() switch (their mocks previously stubbed _apiJson, which the apply call no longer goes through), plus a new test pinning that the real server error string reaches the toast on a failure. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RqZeHrRS6DYcGcGX2p9EwG
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9a9e542a7d
commit
409a6e65f9
@@ -307,10 +307,9 @@ describe('Custom Model Endpoint Profiles: applying a picked entry', () => {
|
||||
app.run = async () => {};
|
||||
app._runInFlight = false;
|
||||
let applyCalled = false;
|
||||
const realApiJson = app._apiJson.bind(app);
|
||||
app._apiJson = async (path: string, opts?: unknown) => {
|
||||
app._api = async (path: string) => {
|
||||
if (path.includes('/custom-model')) applyCalled = true;
|
||||
return realApiJson(path, opts as never);
|
||||
return { ok: true, json: async () => ({ success: true, data: {} }) };
|
||||
};
|
||||
|
||||
await app.runCustomModelEntry('claude', 'llama-box', 'qwen3');
|
||||
@@ -326,9 +325,12 @@ describe('Custom Model Endpoint Profiles: applying a picked entry', () => {
|
||||
app.activeSessionId = 'new-session';
|
||||
};
|
||||
const calls: Array<{ path: string; body: unknown }> = [];
|
||||
app._apiJson = async (path: string, opts?: { body?: unknown }) => {
|
||||
app._api = async (path: string, opts?: { body?: unknown }) => {
|
||||
calls.push({ path, body: opts?.body });
|
||||
return { customModel: { endpointId: 'llama-box' }, restarted: true };
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({ success: true, data: { customModel: { endpointId: 'llama-box' }, restarted: true } }),
|
||||
};
|
||||
};
|
||||
|
||||
await app.runCustomModelEntry('claude', 'llama-box', 'qwen3');
|
||||
@@ -338,6 +340,33 @@ describe('Custom Model Endpoint Profiles: applying a picked entry', () => {
|
||||
expect(calls[0].body).toEqual({ endpointId: 'llama-box', modelId: 'qwen3' });
|
||||
});
|
||||
|
||||
it('surfaces the real server error in the toast on a failed apply, rather than a generic message', async () => {
|
||||
const { app } = bootApp({});
|
||||
app.activeSessionId = 'old-session';
|
||||
app.run = async () => {
|
||||
app.activeSessionId = 'new-session';
|
||||
};
|
||||
app._api = async () => ({
|
||||
ok: false,
|
||||
status: 400,
|
||||
json: async () => ({
|
||||
success: false,
|
||||
error: 'Custom model endpoints are not supported for remote (SSH) or Docker sessions yet',
|
||||
}),
|
||||
});
|
||||
let toastMessage: string | null = null;
|
||||
let toastType: string | null = null;
|
||||
app.showToast = (msg: string, type: string) => {
|
||||
toastMessage = msg;
|
||||
toastType = type;
|
||||
};
|
||||
|
||||
await app.runCustomModelEntry('claude', 'llama-box', 'qwen3');
|
||||
|
||||
expect(toastMessage).toContain('Custom model endpoints are not supported for remote (SSH) or Docker sessions yet');
|
||||
expect(toastType).toBe('error');
|
||||
});
|
||||
|
||||
it('routes through run() itself, so the Run in-flight lock actually engages', async () => {
|
||||
// CLAUDE.md, Run launch synchronization: the lock exists so a double click
|
||||
// cannot create duplicate sessions. A hardcoded dispatch table bypassing
|
||||
|
||||
Reference in New Issue
Block a user