odysseus-dev/odysseus · error · Error

HTTP ${r.status}

Error message

HTTP ${r.status}

What it means

Thrown by _deleteNoteApi in notes.js when DELETE /api/notes/{id} returns non-ok. Per the inline comment this was deliberate: the function used to swallow 4xx/5xx, and now throws 'HTTP <status>' so callers can distinguish success from failure and toast accordingly.

Source

Thrown at static/js/notes.js:479

}

async function _saveNote(note) {
  const method = note.id ? 'PUT' : 'POST';
  const url = note.id ? `${API_BASE}/api/notes/${note.id}` : `${API_BASE}/api/notes`;
  const res = await fetch(url, {
    method, credentials: 'same-origin',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(note),
  });
  if (!res.ok) throw new Error('Failed to save note');
  return await res.json();
}

async function _deleteNoteApi(id) {
  // v2 review — used to swallow 4xx/5xx silently. Throw so callers can
  // distinguish success vs failure and toast accordingly.
  const r = await fetch(`${API_BASE}/api/notes/${id}`, { method: 'DELETE', credentials: 'same-origin' });
  if (!r.ok) throw new Error('HTTP ' + r.status);
}

async function _patchNote(id, patch) {
  const res = await fetch(`${API_BASE}/api/notes/${id}`, {
    method: 'PUT', credentials: 'same-origin',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(patch),
  });
  if (!res.ok) throw new Error('Failed to update note');
  return await res.json();
}

// ---- Helpers ----

function _esc(s) { return uiModule.esc ? uiModule.esc(s || '') : (s || '').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }
function _attrEsc(s) {
  return String(s || '')
    .replace(/"/g, '&quot;')

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Treat 404 as success (note already gone) in the caller, then refresh the list.
  2. For 500, check write permissions on the notes storage backend.
  3. Reload the notes module to resync state and retry.

Example fix

// before
if (!r.ok) throw new Error('HTTP ' + r.status);

// after (idempotent delete)
if (!r.ok && r.status !== 404) throw new Error('HTTP ' + r.status);
Defensive patterns

Strategy: try-catch

Try / catch

try { await _deleteNoteApi(id); } catch (e) { if (e.message.includes('404')) { /* already gone — treat as success */ } else { toast('Delete failed: ' + e.message); } } finally { refreshList(); }

Prevention

When it happens

Trigger: Deleting a note that was already deleted server-side (404); notes store file locked or unwritable (500); expired credentials (401).

Common situations: Double-clicking delete or having the same notes open in two tabs; server data reset while the UI list was cached.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/1657fddec9616458. Report an issue: GitHub.