fix(npm): show timeout hint on first retry (#1538)
Co-Authored-By: jieshu666 <jieshu666@users.noreply.github.com>
This commit is contained in:
@@ -439,6 +439,41 @@ target/debug/build/libsqlite3-sys-*/build-script-build
|
||||
# fine — the AV is blocking Cargo's process-spawning path specifically.
|
||||
```
|
||||
|
||||
### npm binary download times out
|
||||
|
||||
If `deepseek` waits several seconds and prints `connect ETIMEDOUT` or
|
||||
`EAI_AGAIN` while fetching from `github.com`, the npm wrapper installed
|
||||
successfully but the prebuilt binary download from GitHub Releases is blocked
|
||||
or unreliable on your network. This download is separate from the npm registry
|
||||
package download.
|
||||
|
||||
Use one of these paths:
|
||||
|
||||
1. Set a proxy and retry:
|
||||
|
||||
```bash
|
||||
export HTTPS_PROXY=http://your-proxy:port
|
||||
deepseek
|
||||
```
|
||||
|
||||
2. Mirror the release assets internally and set `DEEPSEEK_TUI_RELEASE_BASE_URL`:
|
||||
|
||||
```bash
|
||||
export DEEPSEEK_TUI_RELEASE_BASE_URL=https://your-mirror.example.com/DeepSeek-TUI/
|
||||
deepseek
|
||||
```
|
||||
|
||||
The directory must contain `deepseek-artifacts-sha256.txt` and the platform
|
||||
binaries from the GitHub release.
|
||||
|
||||
3. Install via Cargo, which builds locally and does not download GitHub release
|
||||
assets. See [Section 3](#3-install-via-cargo-any-tier-1-rust-target).
|
||||
|
||||
4. Download both `deepseek` and `deepseek-tui` manually from the
|
||||
[Releases page](https://github.com/Hmbown/DeepSeek-TUI/releases), place them
|
||||
in a directory on `PATH`, and make them executable. See
|
||||
[Section 4](#4-manual-download-from-github-releases).
|
||||
|
||||
---
|
||||
|
||||
## 7. Verifying your install
|
||||
|
||||
@@ -195,7 +195,7 @@ function installFailureHint(error) {
|
||||
" If GitHub is unavailable on this network, mirror the release assets and set:",
|
||||
" DEEPSEEK_TUI_RELEASE_BASE_URL=https://<mirror>/<release-asset-directory>/",
|
||||
" The directory must contain deepseek-artifacts-sha256.txt and the platform binaries.",
|
||||
" See docs/INSTALL.md#npm-download-is-slow-or-times-out-from-mainland-china.",
|
||||
" See docs/INSTALL.md#npm-binary-download-times-out.",
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
@@ -790,6 +790,12 @@ async function withRetry(label, fn, context = "runtime") {
|
||||
logInfo(
|
||||
`${label} failed (attempt ${attempt}/${attemptLimit}): ${err.message}; retrying in ${wait} ms`,
|
||||
);
|
||||
if (attempt === 1) {
|
||||
const hint = installFailureHint(err);
|
||||
if (hint) {
|
||||
process.stderr.write(`${hint}\n`);
|
||||
}
|
||||
}
|
||||
await sleep(wait);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ test("install failure hint explains release base override for blocked GitHub dow
|
||||
assert.match(hint, /DEEPSEEK_TUI_RELEASE_BASE_URL/);
|
||||
assert.match(hint, /deepseek-artifacts-sha256\.txt/);
|
||||
assert.match(hint, /platform binaries/);
|
||||
assert.match(hint, /#npm-binary-download-times-out/);
|
||||
} finally {
|
||||
if (previous === undefined) {
|
||||
delete process.env.DEEPSEEK_TUI_RELEASE_BASE_URL;
|
||||
|
||||
@@ -89,3 +89,42 @@ test("optional install still swallows wrapped http 5xx failures", async () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("withRetry prints install hint on first retryable failure", async () => {
|
||||
const previousWrite = process.stderr.write;
|
||||
const previousSetTimeout = global.setTimeout;
|
||||
let stderr = "";
|
||||
let attempts = 0;
|
||||
process.stderr.write = (chunk) => {
|
||||
stderr += String(chunk);
|
||||
return true;
|
||||
};
|
||||
global.setTimeout = (callback) => {
|
||||
callback();
|
||||
return 0;
|
||||
};
|
||||
|
||||
try {
|
||||
const result = await _internal.withRetry(
|
||||
"fetch https://github.com/example",
|
||||
async () => {
|
||||
attempts += 1;
|
||||
if (attempts === 1) {
|
||||
const err = new Error("connect ETIMEDOUT 20.205.243.166:443");
|
||||
err.code = "ETIMEDOUT";
|
||||
throw err;
|
||||
}
|
||||
return "ok";
|
||||
},
|
||||
"runtime",
|
||||
);
|
||||
|
||||
assert.equal(result, "ok");
|
||||
assert.equal(attempts, 2);
|
||||
assert.match(stderr, /deepseek-tui install hint:/);
|
||||
assert.match(stderr, /#npm-binary-download-times-out/);
|
||||
} finally {
|
||||
process.stderr.write = previousWrite;
|
||||
global.setTimeout = previousSetTimeout;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user