feat(timeout): show duration, URL, and config hint on timeouts; increase fetch timeout default to 10s#5991
Conversation
…ase fetch timeout default to 10s - HTTP errors now display the timeout (e.g. 10s), the requested URL, and how to change it (`http_timeout`/MISE_HTTP_TIMEOUT or `fetch_remote_versions_timeout`/MISE_FETCH_REMOTE_VERSIONS_TIMEOUT) - Fetch tasks include duration and config hint in timeout errors - Default `fetch_remote_versions_timeout` increased from 5s to 10s
There was a problem hiding this comment.
Pull Request Overview
This PR enhances timeout error messaging and increases the default timeout for fetching remote tool versions from 5s to 10s. The changes improve user experience by providing more informative timeout errors with specific configuration guidance.
- Improved timeout error messages to include duration, URL, and configuration hints
- Enhanced HTTP client error handling to provide specific configuration guidance for different client types
- Increased default
fetch_remote_versions_timeoutfrom 5s to 10s
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/timeout.rs | Enhanced timeout error messages to include formatted duration |
| src/plugins/core/mod.rs | Added configuration hint to fetch timeout errors |
| src/http.rs | Refactored HTTP client with improved timeout error handling and configuration guidance |
| settings.toml | Updated default fetch timeout from 5s to 10s |
| ensure!(!*env::OFFLINE, "offline mode is enabled"); | ||
| let get = |url: Url| async move { | ||
| let mut url = url.into_url().unwrap(); | ||
| let do_get = |url: Url, |
There was a problem hiding this comment.
The do_get closure has too many parameters (5) and duplicates logic with do_head. Consider extracting this into a separate method or struct to reduce code duplication and improve maintainability.
| ) -> Result<Response> { | ||
| ensure!(!*env::OFFLINE, "offline mode is enabled"); | ||
| let head = |url: Url| async move { | ||
| let mut url = url.into_url().unwrap(); |
There was a problem hiding this comment.
The do_head closure duplicates significant logic with do_get (lines 98-126 are nearly identical to 188-216). Consider extracting the common timeout error handling logic into a shared helper function.
| let mut url = url.into_url().unwrap(); | |
| let mut url = url.into_url().unwrap(); | |
| fn handle_timeout_error( | |
| err: reqwest::Error, | |
| timeout: Duration, | |
| url: &Url, | |
| kind: ClientKind, | |
| ) -> Result<()> { | |
| if err.is_timeout() { | |
| let (setting, env_var) = match kind { | |
| ClientKind::Http => ("http_timeout", "MISE_HTTP_TIMEOUT"), | |
| ClientKind::Fetch => ( | |
| "fetch_remote_versions_timeout", | |
| "MISE_FETCH_REMOTE_VERSIONS_TIMEOUT", | |
| ), | |
| ClientKind::VersionCheck => ("version_check_timeout", ""), | |
| }; | |
| let hint = if env_var.is_empty() { | |
| format!( | |
| "HTTP timed out after {} for {}.", | |
| format_duration(timeout), | |
| url | |
| ) | |
| } else { | |
| format!( | |
| "HTTP timed out after {} for {} (change with `{}` or env `{}`).", | |
| format_duration(timeout), | |
| url, | |
| setting, | |
| env_var | |
| ) | |
| }; | |
| bail!(hint); | |
| } | |
| Err(err.into()) | |
| } |
| ClientKind::VersionCheck => ("version_check_timeout", ""), | ||
| }; | ||
| let hint = if env_var.is_empty() { | ||
| format!( |
There was a problem hiding this comment.
The VersionCheck client kind references a non-existent version_check_timeout setting. Based on the client initialization, it should be a hardcoded "3s" or reference an actual setting name.
| format!( | |
| ClientKind::VersionCheck => ("", ""), | |
| }; | |
| let hint = if kind == ClientKind::VersionCheck { | |
| format!( | |
| "HTTP timed out after {} for {} (timeout is hardcoded to 3s for version check).", | |
| format_duration(timeout), | |
| url | |
| ) | |
| } else if env_var.is_empty() { | |
| format!( |
|
bugbot run |
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.8.8 x -- echo |
18.8 ± 0.5 | 17.9 | 22.7 | 1.00 |
mise x -- echo |
19.3 ± 0.8 | 18.2 | 24.7 | 1.03 ± 0.05 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.8.8 env |
18.2 ± 0.5 | 17.3 | 20.0 | 1.00 |
mise env |
18.3 ± 0.6 | 17.4 | 20.6 | 1.01 ± 0.04 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.8.8 hook-env |
17.8 ± 0.5 | 17.0 | 21.2 | 1.00 |
mise hook-env |
18.3 ± 0.7 | 17.1 | 20.4 | 1.03 ± 0.05 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2025.8.8 ls |
16.7 ± 0.5 | 15.9 | 20.0 | 1.00 ± 0.04 |
mise ls |
16.7 ± 0.4 | 16.0 | 19.0 | 1.00 |
xtasks/test/perf
| Command | mise-2025.8.8 | mise | Variance |
|---|---|---|---|
| install (cached) | 192ms | ✅ 130ms | +47% |
| ls (cached) | 81ms | 83ms | -2% |
| bin-paths (cached) | 66ms | 66ms | +0% |
| task-ls (cached) | 488ms | 487ms | +0% |
✅ Performance improvement: install cached is 47%
### 📦 Registry - add vfox-yarn as primary yarn backend by [@jdx](https://github.com/jdx) in [#5982](#5982) - add missing description field for a lot of tools by [@jylenhof](https://github.com/jylenhof) in [#5966](#5966) - rename benthos to redpanda-connect by [@risu729](https://github.com/risu729) in [#5984](#5984) - rename coq to rocq by [@risu729](https://github.com/risu729) in [#5985](#5985) ### 🚀 Features - **(timeout)** show duration, URL, and config hint on timeouts; increase fetch timeout default to 10s by [@jdx](https://github.com/jdx) in [#5991](#5991) ### 🐛 Bug Fixes - **(aqua)** add executable permissions for zip-extracted binaries by [@itochan](https://github.com/itochan) in [#5998](#5998) - **(core)** auto-repair corrupted pyenv cache by recloning on update failure by [@jdx](https://github.com/jdx) in [#6003](#6003) - duplicate versions and validation in `mise tool` by [@jdx](https://github.com/jdx) in [#6001](#6001) ### 📚 Documentation - **(tools)** document per-tool postinstall option in [tools] by [@jdx](https://github.com/jdx) in [#5993](#5993) - Update install instructions for nushell by [@Joniator](https://github.com/Joniator) in [#5981](#5981) - README.md typo by [@jdx](https://github.com/jdx) in [#5990](#5990) ###◀️ Revert - Revert "docs: Update install instructions for nushell" by [@jdx](https://github.com/jdx) in [#5983](#5983) - Revert "fix(aqua): add executable permissions for zip-extracted binaries" by [@jdx](https://github.com/jdx) in [#6004](#6004) ### 📦️ Dependency Updates - update taiki-e/install-action digest to 2c73a74 by [@renovate[bot]](https://github.com/renovate[bot]) in [#5962](#5962) - update docker/metadata-action digest to c1e5197 by [@renovate[bot]](https://github.com/renovate[bot]) in [#5961](#5961) - update docker/login-action digest to 184bdaa by [@renovate[bot]](https://github.com/renovate[bot]) in [#5958](#5958) ### Chore - cargo up by [@jdx](https://github.com/jdx) in [#5992](#5992) ### New Contributors - @Joniator made their first contribution in [#5981](#5981) - @jylenhof made their first contribution in [#5966](#5966)
http_timeout/MISE_HTTP_TIMEOUT orfetch_remote_versions_timeout/MISE_FETCH_REMOTE_VERSIONS_TIMEOUT)fetch_remote_versions_timeoutincreased from 5s to 10s