* 使用系统已安装的 speedtest 可执行文件运行测试 * 优先尝试 `speedtest`,如果不存在再尝试 `speedtest-cli`
(serverId?: number, retryCount: number = 0)
| 552 | let exe: string | null = null; |
| 553 | |
| 554 | for (const name of candidates) { |
| 555 | try { |
| 556 | // which 返回路径或者抛错 |
| 557 | const { stdout } = await execAsync(`which ${name}`, { timeout: 5000 }); |
| 558 | if (stdout && stdout.trim()) { |
| 559 | exe = stdout.trim(); |
| 560 | break; |
| 561 | } |
| 562 | } catch (e) { |
| 563 | // ignore |
| 564 | } |
| 565 | } |
| 566 | |
| 567 | if (!exe) { |
| 568 | // on windows try where |
| 569 | if (process.platform === 'win32') { |
| 570 | for (const name of ['speedtest', 'speedtest-cli']) { |
| 571 | try { |
| 572 | const { stdout } = await execAsync(`where ${name}`, { timeout: 5000 }); |
| 573 | if (stdout && stdout.trim()) { |
| 574 | exe = stdout.split(/\r?\n/)[0].trim(); |
| 575 | break; |
| 576 | } |
| 577 | } catch { } |
| 578 | } |
| 579 | } |
| 580 | } |
| 581 | |
| 582 | if (!exe) { |
| 583 | throw new Error('系统未安装 speedtest,可使用不带 --system 的默认行为或运行 .speedtest update 安装内置 CLI'); |
| 584 | } |
| 585 | |
| 586 | const serverArg = serverId ? ` -s ${serverId}` : ''; |
| 587 | const command = `${exe} --accept-license --accept-gdpr -f json${serverArg}`; |
| 588 | |
| 589 | const { stdout, stderr } = await execAsync(command, { timeout: 120000 }); |
| 590 | |
| 591 | if (stderr && stderr.trim()) { |
| 592 | console.log('System speedtest stderr:', stderr); |
| 593 | } |
| 594 | |
| 595 | let result: any; |
| 596 | try { |
| 597 | result = JSON.parse(stdout); |
| 598 | |
| 599 | // 检查JSON中是否包含错误信息 |
| 600 | if (result.error) { |
| 601 | if (result.error.includes("Cannot read")) { |
| 602 | throw new Error(`网络连接错误: ${result.error}\n\n这是网络环境问题,不是程序问题。建议:\n1. 检查网络连接稳定性\n2. 尝试其他测试服务器\n3. 稍后重试`); |
| 603 | } |
| 604 | throw new Error(`测试失败: ${result.error}`); |
| 605 | } |
| 606 | } catch (parseError) { |
| 607 | if (stdout.includes('"error":"Cannot read')) { |
| 608 | throw new Error('网络连接错误: Cannot read\n\n这是网络环境问题,不是程序问题。建议:\n1. 检查网络连接稳定性\n2. 尝试其他测试服务器\n3. 稍后重试'); |
| 609 | } |
| 610 | throw new Error('系统 speedtest 返回非 JSON 输出'); |
| 611 | } |
no test coverage detected