{"record":{"id":"7d528cf884b1aa3d","repo":"danielmiessler/Fabric","slug":"await-response-text","errorCode":null,"errorMessage":"await response.text()","messagePattern":"await response\\.text\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/lib/store/note-store.ts","lineNumber":76,"sourceCode":"updated: ${frontmatter.updated}\nauthor: ${frontmatter.author}\n---\n\n${content}`;\n\n      const response = await fetch('/notes', {\n          method: 'POST',\n          headers: {\n              'Content-Type': 'application/json',\n          },\n          body: JSON.stringify({\n              filename,\n              content: fileContent\n          })\n      });\n\n      if (!response.ok) {\n          throw new Error(await response.text());\n      }\n\n      return filename;\n  };\n\n  return {\n      subscribe,\n      updateContent: (content: string) => update(state => ({\n          ...state,\n          content,\n          isDirty: true\n      })),\n      save: async () => {\n          const state = get({ subscribe });\n          const filename = await saveToFile(state.content);\n\n          update(state => ({\n              ...state,","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/danielmiessler/Fabric/blob/338b89cfe97ab2d12ce30ce8b5449857a841366d/web/src/lib/store/note-store.ts#L58-L94","documentation":"note-store's save throws the raw response body text when POST /notes responds non-OK: throw new Error(await response.text()). Unlike other clients there is no envelope parsing — whatever the server wrote (plain text, HTML error page, JSON string) becomes the Error message verbatim.","triggerScenarios":"POST /notes with a filename the server rejects (invalid chars, too long), body too large for the proxy, or server IO failure writing the note file.","commonSituations":"Filename containing '/' or '..'; nginx default 1MB body limit rejecting large notes; backend route /notes (no /api prefix) not proxied in dev, returning the dev server's 404 HTML as the error message.","solutions":["Look at the thrown message content: HTML usually means a proxy 404/413 page, JSON/plain text means the notes handler","Sanitize the filename before saving (strip path separators, trim)","Raise client_max_body_size on the proxy if large notes are rejected","If 404 HTML appears, fix the proxy to forward /notes to the backend"],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error(await response.text());\n}\n\n// after\nif (!response.ok) {\n  const body = await response.text();\n  let msg = body;\n  try { msg = JSON.parse(body).error || body; } catch {}\n  throw new Error(`Saving note failed (HTTP ${response.status}): ${msg.slice(0, 200)}`);\n}","handlingStrategy":"validation","validationCode":"function isValidNoteFilename(f: string): boolean {\n  return /^[-\\w. ]{1,120}$/.test(f) && !f.includes('..');\n}\nif (!isValidNoteFilename(filename)) throw new Error('Invalid note filename');","typeGuard":"function isNoteSaveFailure(e: unknown): boolean {\n  return e instanceof Error && /Saving note failed|^\\s*<(!doctype|html)/i.test(e.message);\n}","tryCatchPattern":"try { await saveNote(filename, content); }\ncatch (e) {\n  const msg = e instanceof Error ? e.message : '';\n  if (/^\\s*<(!doctype|html)/i.test(msg)) throw new Error('Notes backend unreachable (proxy 404/413)');\n  throw new Error(`Note save failed: ${msg.slice(0, 200)}`);\n}","preventionTips":["Validate/trim filenames before POST /notes","Detect HTML error pages in thrown text and translate to a clear message","Confirm the proxy forwards /notes with adequate body limits"],"tags":["notes","http","api-client","proxy"],"backgroundTag":null,"analyzedSha":"338b89cfe97ab2d12ce30ce8b5449857a841366d","analyzedAt":"2026-08-15T11:38:51.759Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}