From 7642a17b578379ace7c0a1c6b93746031c5be4d1 Mon Sep 17 00:00:00 2001 From: Kroese Date: Wed, 15 Jul 2026 11:34:26 +0200 Subject: [PATCH] feat: Improve curl error reporting (#1855) --- src/mido.sh | 197 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 121 insertions(+), 76 deletions(-) diff --git a/src/mido.sh b/src/mido.sh index 09897cd1..dd720216 100644 --- a/src/mido.sh +++ b/src/mido.sh @@ -5,46 +5,85 @@ handleCurlError() { local code="$1" local server="$2" + local reason="${3:-}" + local signal="" + + if [ -n "$reason" ] && (( code <= 125 )); then + error "Request to $server servers failed: ${reason%.}." + return 1 + fi case "$code" in - 1) error "Unsupported protocol!" ;; - 2) error "Failed to initialize curl!" ;; - 3) error "The URL format is malformed!" ;; - 5) error "Failed to resolve address of proxy host!" ;; - 6) error "Failed to resolve $server servers! Is there an Internet connection?" ;; - 7) error "Failed to contact $server servers! Is there an Internet connection or is the server down?" ;; - 8) error "$server servers returned a malformed HTTP response!" ;; - 16) error "A problem was detected in the HTTP2 framing layer!" ;; - 22) error "$server servers returned a failing HTTP status code!" ;; - 23) error "Failed at writing Windows media to disk! Out of disk space or permission error?" ;; - 26) error "Failed to read Windows media from disk!" ;; - 27) error "Ran out of memory during download!" ;; - 28) error "Connection timed out to $server server!" ;; - 35) error "SSL connection error from $server server!" ;; - 36) error "Failed to continue earlier download!" ;; - 52) error "Received no data from the $server server!" ;; - 63) error "$server servers returned an unexpectedly large response!" ;; - 126) error "Curl command cannot be executed!" ;; - 127) error "Curl command not found!" ;; + 126) error "The curl command could not be executed." ;; + 127) error "The curl command was not found." ;; *) - if (( code <= 125 )); then - # Must be some other server or network error (possibly with this specific request/file) - # This is when accounting for all possible errors in the curl manual assuming a correctly formed - # curl command and an HTTP(S) request, using only the curl features we're using, and a sane build. - error "Miscellaneous server or network error, reason: $code" - else - case "$(kill -l "$code" 2>/dev/null || true)" in - INT) error "Curl was interrupted!" ;; - SEGV | ABRT) error "Curl crashed! Please report any core dumps to curl developers." ;; - *) error "Curl terminated due to fatal signal $code !" ;; - esac + if (( code < 129 )); then + error "Request to $server servers failed with curl exit status $code." + return 1 fi + + signal=$(kill -l "$((code - 128))" 2>/dev/null || true) + + case "$signal" in + INT) error "Curl was interrupted." ;; + SEGV | ABRT) error "Curl crashed with signal $signal." ;; + "") error "Curl terminated with exit status $code." ;; + *) error "Curl terminated due to signal $signal." ;; + esac ;; esac return 1 } +curlRequest() { + + local output="$1" + local server="$2" + local agent="$3" + shift 3 + + local log reason + local rc=0 response="" + + if ! log=$(mktemp); then + error "Failed to create a temporary curl log." + return 1 + fi + + { + response=$(LC_ALL=C curl \ + --silent \ + --show-error \ + --max-time 30 \ + --user-agent "$agent" \ + --fail \ + --proto =https \ + --tlsv1.2 \ + --http1.1 \ + "$@" 2>"$log") + rc=$? + } || : + + if (( rc != 0 )); then + + reason=$(sed -nE 's/^curl: \([0-9]+\) //p' "$log" | tail -n 1) + + rm -f "$log" + handleCurlError "$rc" "$server" "$reason" + + return 1 + fi + + rm -f "$log" + + if [ -n "$output" ]; then + printf -v "$output" '%s' "$response" + fi + + return 0 +} + getAgent() { local browser_version @@ -62,15 +101,14 @@ downloadWindows() { local lang="$2" local desc="$3" - local rc=0 local ovToken="" ovTicks="" ovTime="" local skuId="" skuUrl="" skuJson="" local linkUrl="" linkJson="" link="" - local language="" orgId="" - local instance="" vlsUrl="" ovUrl="" ovData="" + local language="" orgId="" ovData="" + local instance="" vlsUrl="" ovUrl="" local session="" agent="" type="" local winVer="" page="" productId="" - local profile="606624d44113" + local rc=0 profile="606624d44113" agent=$(getAgent) language=$(getLanguage "$lang" "name") @@ -102,10 +140,11 @@ downloadWindows() { # Also, keeping a "$WindowsVersions" array like Fido does would be way too much of a maintenance burden # Remove "Accept" header that curl sends by default enabled "$DEBUG" && echo "Parsing download page: ${url}" - page=$(curl --silent --max-time 30 --user-agent "$agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || { - handleCurlError "$?" "Microsoft" - return $? - } + + curlRequest page "Microsoft" "$agent" \ + --header "Accept:" \ + --max-filesize 1M \ + -- "$url" || return 1 enabled "$DEBUG" && echo -n "Getting Product edition ID: " productId=$(echo "$page" | grep -Eo '