mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 08:59:40 +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
@@ -5484,12 +5484,25 @@ Object.assign(CodemanApp.prototype, {
|
||||
return this.showToast(message, type);
|
||||
},
|
||||
|
||||
/**
|
||||
* `duration` defaults to 0 (sticky, no auto-dismiss) for `error` toasts and
|
||||
* 3000ms for everything else — an error worth a distinct visual style is
|
||||
* also worth reading before it vanishes, which a fixed 3s auto-dismiss
|
||||
* does not guarantee: "Session started on the native backend — could not
|
||||
* apply the custom endpoint: <the actual reason>" is exactly the kind of
|
||||
* message that needs a moment to read, not a glance. Every toast gets an
|
||||
* explicit close button regardless of duration, since a sticky one with no
|
||||
* way to dismiss it would just pile up. A caller can still override either
|
||||
* default via `opts.duration` (e.g. a deliberately brief success toast, or
|
||||
* a non-error one that should also stay put).
|
||||
*/
|
||||
showToast(message, type = 'info', opts = {}) {
|
||||
const { duration = 3000, action } = opts;
|
||||
const { duration = type === 'error' ? 0 : 3000, action } = opts;
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `toast toast-${type}`;
|
||||
|
||||
const msgSpan = document.createElement('span');
|
||||
msgSpan.className = 'toast-message';
|
||||
msgSpan.textContent = message;
|
||||
toast.appendChild(msgSpan);
|
||||
|
||||
@@ -5501,6 +5514,20 @@ Object.assign(CodemanApp.prototype, {
|
||||
toast.appendChild(btn);
|
||||
}
|
||||
|
||||
let dismissTimer = null;
|
||||
const dismiss = () => {
|
||||
if (dismissTimer) clearTimeout(dismissTimer);
|
||||
toast.classList.remove('show');
|
||||
setTimeout(() => toast.remove(), 200);
|
||||
};
|
||||
|
||||
const closeBtn = document.createElement('button');
|
||||
closeBtn.className = 'toast-close';
|
||||
closeBtn.textContent = '×';
|
||||
closeBtn.setAttribute('aria-label', 'Dismiss');
|
||||
closeBtn.onclick = (e) => { e.stopPropagation(); dismiss(); };
|
||||
toast.appendChild(closeBtn);
|
||||
|
||||
// Cache toast container reference
|
||||
if (!this._toastContainer) {
|
||||
this._toastContainer = document.querySelector('.toast-container');
|
||||
@@ -5514,10 +5541,9 @@ Object.assign(CodemanApp.prototype, {
|
||||
|
||||
requestAnimationFrame(() => toast.classList.add('show'));
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
setTimeout(() => toast.remove(), 200);
|
||||
}, duration);
|
||||
if (duration > 0) {
|
||||
dismissTimer = setTimeout(dismiss, duration);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user