WIP: fix: "Failed to fetch" auf Hetzner — Job-Polling statt Langläufer-Request #10

Draft
Kenearos wants to merge 1 commit from claude/hetzner-fetch-failure-hlljm0 into main
Kenearos commented 2026-06-19 12:15:59 +02:00 (Migrated from github.com)

Problem

Auf dem Hetzner-Server zeigt die UI „Failed to fetch" (siehe Screenshot des Users), sobald „Analysieren & Ausfüllen" geklickt wird.

Wichtige Diagnose: „Failed to fetch" ist die wörtliche Browser-Meldung für eine abgewiesene fetch()-Promise — der Browser bekommt gar keine HTTP-Antwort. Ein kaputtes claude -p würde dagegen vom Server als sauberes JSON (502 {error, details}) zurückkommen und im Frontend als lesbarer Text erscheinen. Die Meldung deutet also auf die Transport-Ebene, nicht auf Claude-Logik.

Ursache

POST /api/process hielt die HTTP-Verbindung 30–120 s+ offen, während claude -p als Subprozess lief. Hinter einem Reverse-Proxy (Container hängt im matrix_default-Netz) kappt dessen Read-/Idle-Timeout so eine Langläufer-Verbindung, bevor Claude fertig ist → Verbindung gedroppt ohne saubere Antwort → „Failed to fetch". Gleiches gilt bei kurzen Netz-Hängern oder einem Container-Neustart mitten in der Anfrage.

Fix: Job-Pattern

  • Server (server/index.ts): POST /api/process registriert einen Job und antwortet sofort mit 202 {jobId}. claude läuft im Hintergrund; Ergebnis bzw. Fehler landen in einem In-Memory-Job-Store (TTL 15 min, periodische Bereinigung). Neuer GET /api/process/:jobId liefert pending / done / error in kurzen, proxy-sicheren Requests. Temp-Verzeichnis wird erst nach Job-Ende aufgeräumt.
  • Frontend (services/api.ts): pollt den Job alle 2 s. Ein transienter Netzfehler beim Pollen wird erneut versucht (bis 8x in Folge) statt die Analyse abzubrechen. Echte Claude-Fehler werden jetzt als Klartext angezeigt statt als „Failed to fetch".

Damit kann der Proxy keine Langläufer-Verbindung mehr abschneiden, und transiente Abbrüche werden automatisch überbrückt.

Test

  • npm run typecheck
  • npm run build scheitert im CI-Container nur am fehlenden Schwester-Repo ../kanagawa-design-system/ (Build-Context-Detail, unabhängig von dieser Änderung).

Hinweis zur Server-Diagnose

Falls nach dem Deploy weiterhin Probleme auftreten, lohnt sich am Server: docker logs rentenv, docker exec rentenv wget -qO- http://127.0.0.1:3011/api/health und ein direkter claude -p-Test im Container, um Auth/Hang auszuschließen.

🤖 Generated with Claude Code


Generated by Claude Code

## Problem Auf dem Hetzner-Server zeigt die UI **„Failed to fetch"** (siehe Screenshot des Users), sobald „Analysieren & Ausfüllen" geklickt wird. Wichtige Diagnose: „Failed to fetch" ist die wörtliche Browser-Meldung für eine abgewiesene `fetch()`-Promise — **der Browser bekommt gar keine HTTP-Antwort**. Ein kaputtes `claude -p` würde dagegen vom Server als sauberes JSON (`502 {error, details}`) zurückkommen und im Frontend als lesbarer Text erscheinen. Die Meldung deutet also auf die **Transport-Ebene**, nicht auf Claude-Logik. ## Ursache `POST /api/process` hielt die HTTP-Verbindung 30–120 s+ offen, während `claude -p` als Subprozess lief. Hinter einem Reverse-Proxy (Container hängt im `matrix_default`-Netz) kappt dessen Read-/Idle-Timeout so eine Langläufer-Verbindung, bevor Claude fertig ist → Verbindung gedroppt ohne saubere Antwort → „Failed to fetch". Gleiches gilt bei kurzen Netz-Hängern oder einem Container-Neustart mitten in der Anfrage. ## Fix: Job-Pattern - **Server** (`server/index.ts`): `POST /api/process` registriert einen Job und antwortet **sofort** mit `202 {jobId}`. `claude` läuft im Hintergrund; Ergebnis bzw. Fehler landen in einem In-Memory-Job-Store (TTL 15 min, periodische Bereinigung). Neuer **`GET /api/process/:jobId`** liefert `pending` / `done` / `error` in kurzen, proxy-sicheren Requests. Temp-Verzeichnis wird erst nach Job-Ende aufgeräumt. - **Frontend** (`services/api.ts`): pollt den Job alle 2 s. Ein transienter Netzfehler beim Pollen wird erneut versucht (bis 8x in Folge) statt die Analyse abzubrechen. Echte Claude-Fehler werden jetzt als **Klartext** angezeigt statt als „Failed to fetch". Damit kann der Proxy keine Langläufer-Verbindung mehr abschneiden, und transiente Abbrüche werden automatisch überbrückt. ## Test - `npm run typecheck` ✅ - `npm run build` scheitert im CI-Container nur am fehlenden Schwester-Repo `../kanagawa-design-system/` (Build-Context-Detail, unabhängig von dieser Änderung). ## Hinweis zur Server-Diagnose Falls nach dem Deploy weiterhin Probleme auftreten, lohnt sich am Server: `docker logs rentenv`, `docker exec rentenv wget -qO- http://127.0.0.1:3011/api/health` und ein direkter `claude -p`-Test im Container, um Auth/Hang auszuschließen. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Generated by [Claude Code](https://claude.ai/code/session_01P7fRh8N5kQsicT7q4gSnua)_
coderabbitai[bot] commented 2026-06-19 12:16:07 +02:00 (Migrated from github.com)

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 08523bfa-78cc-440d-b373-0b72e850a991

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/hetzner-fetch-failure-hlljm0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- This is an auto-generated comment: skip review by coderabbit.ai --> > [!IMPORTANT] > ## Review skipped > > Draft detected. > > Please check the settings in the CodeRabbit UI or the `.coderabbit.yaml` file in this repository. To trigger a single review, invoke the `@coderabbitai review` command. > > <details> > <summary>⚙️ Run configuration</summary> > > **Configuration used**: defaults > > **Review profile**: CHILL > > **Plan**: Pro > > **Run ID**: `08523bfa-78cc-440d-b373-0b72e850a991` > > </details> > > You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file. > > Use the checkbox below for a quick retry: > - [ ] <!-- {"checkboxId": "e9bb8d72-00e8-4f67-9cb2-caf3b22574fe"} --> 🔍 Trigger review <!-- end of auto-generated comment: skip review by coderabbit.ai --> <!-- finishing_touch_checkbox_start --> <details> <summary>✨ Finishing Touches</summary> <details> <summary>🧪 Generate unit tests (beta)</summary> - [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests - [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `claude/hetzner-fetch-failure-hlljm0` </details> </details> <!-- finishing_touch_checkbox_end --> <!-- tips_start --> --- Thanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Kenearos/Rentenversicherer&utm_content=10)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. <details> <summary>❤️ Share</summary> - [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code) </details> <sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub> <!-- tips_end -->
This pull request is marked as a work in progress.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude/hetzner-fetch-failure-hlljm0:claude/hetzner-fetch-failure-hlljm0
git checkout claude/hetzner-fetch-failure-hlljm0

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git checkout main
git merge --no-ff claude/hetzner-fetch-failure-hlljm0
git checkout claude/hetzner-fetch-failure-hlljm0
git rebase main
git checkout main
git merge --ff-only claude/hetzner-fetch-failure-hlljm0
git checkout claude/hetzner-fetch-failure-hlljm0
git rebase main
git checkout main
git merge --no-ff claude/hetzner-fetch-failure-hlljm0
git checkout main
git merge --squash claude/hetzner-fetch-failure-hlljm0
git checkout main
git merge --ff-only claude/hetzner-fetch-failure-hlljm0
git checkout main
git merge claude/hetzner-fetch-failure-hlljm0
git push origin main
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: its-consulting/Rentenversicherer#10
No description provided.