From 2cf43dd665ab07b5c1c65fa95a55f111968aab3f Mon Sep 17 00:00:00 2001 From: EMRG Evolution Date: Sat, 8 Aug 2026 09:34:44 +0800 Subject: [PATCH] =?UTF-8?q?emrg:=20recognize=20'remote=20end=20hung=20up'?= =?UTF-8?q?=20as=20connection=20error=20in=20https=E2=86=92ssh=20fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Agent.md | 2 +- README.md | 2 +- emrg/server/git_utils.py | 7 +++++++ tests/test_git_utils.py | 11 +++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Agent.md b/Agent.md index c75557cf..bd9a8231 100644 --- a/Agent.md +++ b/Agent.md @@ -93,7 +93,7 @@ Community needs voiced in HN agent-UI discussions map directly to EMRG's design: pkill -f "emrg.server"; rm -f ~/.emrg/emrgd.port; python -m emrg ``` -Python: `uv run pytest tests/ -v` (589) — import check: `uv run python -c "from emrg.client.app import run_client"` +Python: `uv run pytest tests/ -v` (590) — import check: `uv run python -c "from emrg.client.app import run_client"` GUI: `cd emrg/gui && npm test` (93: 22 daemon_client + 22 app-commands + 24 renderer smoke + 15 i18n + 7 integration + 3 commands) — syntax: `node --check main.js preload.js daemon_client.js renderer/js/*.js` CI: `uv run pytest` + GUI tests + **actionlint workflow lint** (`rhysd/actionlint@v1.7.12` gate, #444 — workflow 解析错误在 PR CI 即失败,如 `if:` secrets 上下文) Re-trigger: `scripts/re-trigger-ci.sh [branch]` (workflow_dispatch, #527 — 替代空 commit 重触发:Actions outage 会整段丢弃 push 事件,dispatch 走 API 路径不受影响) diff --git a/README.md b/README.md index c8cae059..e956852e 100644 --- a/README.md +++ b/README.md @@ -273,7 +273,7 @@ EMRG doesn't just keep up — it catches up on its own. git clone https://github.com/argszero/emrg.git cd emrg uv sync # install deps -uv run pytest tests/ -v # run tests (currently 589 items) +uv run pytest tests/ -v # run tests (currently 590 items) uv run python -m emrg # launch TUI # CI includes actionlint workflow gate (#444): workflow parse errors fail PR CI diff --git a/emrg/server/git_utils.py b/emrg/server/git_utils.py index 3ffd93a1..6df4b04b 100644 --- a/emrg/server/git_utils.py +++ b/emrg/server/git_utils.py @@ -84,6 +84,13 @@ def parse_gh_auth_user(output: str) -> str | None: "network is unreachable", "unable to access", "tls handshake timeout", + # "the remote end hung up unexpectedly" / "connection ... hung up" — + # git's classic message when a proxy/network drops the connection + # mid-transfer (observed on the packaged host: fetch fails with + # "fatal: the remote end hung up unexpectedly" while https works via + # proxy on retry). A network-level drop is exactly the case where an + # SSH retry may succeed. + "hung up", ) diff --git a/tests/test_git_utils.py b/tests/test_git_utils.py index c72682ba..ebdc1d00 100644 --- a/tests/test_git_utils.py +++ b/tests/test_git_utils.py @@ -206,6 +206,17 @@ def test_is_git_connection_error_matches_connection_failures(): assert is_git_connection_error("ssh: connect to host github.com port 22: Connection refused") +def test_is_git_connection_error_matches_hung_up(): + """'remote end hung up' (network drop mid-transfer) is a connection error.""" + from emrg.server.git_utils import is_git_connection_error + + assert is_git_connection_error("fatal: the remote end hung up unexpectedly") + assert is_git_connection_error( + "error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: " + "PROTOCOL_ERROR (err 1)\nfatal: the remote end hung up unexpectedly" + ) + + def test_is_git_connection_error_rejects_auth_and_404(): from emrg.server.git_utils import is_git_connection_error