diff --git a/misc/core.func b/misc/core.func index 6b4190caa..220281958 100644 --- a/misc/core.func +++ b/misc/core.func @@ -527,29 +527,23 @@ silent() { fi if [[ $rc -ne 0 ]]; then - # Source explain_exit_code if needed - if ! declare -f explain_exit_code >/dev/null 2>&1; then - if ! source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func); then - explain_exit_code() { echo "unknown (error_handler.func download failed)"; } - fi - fi + # Return instead of exit so that callers can use `$STD cmd || true` + # or `if $STD cmd; then ...` to handle errors gracefully. + # When no || / if is used, set -e + ERR trap will still catch it + # and error_handler() will display the error and exit. + # + # Set flag so error_handler knows to show log tail from silent's logfile + export _SILENT_FAILED_RC="$rc" + export _SILENT_FAILED_CMD="$cmd" + export _SILENT_FAILED_LINE="$caller_line" + export _SILENT_FAILED_LOG="$logfile" - local explanation - explanation="$(explain_exit_code "$rc")" - - printf "\e[?25h" - msg_error "in line ${caller_line}: exit code ${rc} (${explanation})" - msg_custom "→" "${YWB}" "${cmd}" - - if [[ -s "$logfile" ]]; then - echo -e "\n${TAB}--- Last 20 lines of log ---" - tail -n 20 "$logfile" - echo -e "${TAB}-----------------------------------" - echo -e "${TAB}📋 Full log: ${logfile}\n" - fi - - exit "$rc" + return "$rc" fi + + # Clear stale flags on success (prevents false positives if a previous + # $STD cmd || true failed and a later non-silent command triggers error_handler) + unset _SILENT_FAILED_RC _SILENT_FAILED_CMD _SILENT_FAILED_LINE _SILENT_FAILED_LOG 2>/dev/null || true } # ------------------------------------------------------------------------------ diff --git a/misc/error_handler.func b/misc/error_handler.func index bf81ea9bf..dd816dc22 100644 --- a/misc/error_handler.func +++ b/misc/error_handler.func @@ -236,6 +236,16 @@ error_handler() { command="${command//\$STD/}" + # If error originated from silent(), use its captured metadata + # This provides the actual command and line number instead of "silent ..." + if [[ -n "${_SILENT_FAILED_RC:-}" ]]; then + exit_code="$_SILENT_FAILED_RC" + command="$_SILENT_FAILED_CMD" + line_number="$_SILENT_FAILED_LINE" + # Clear flags to prevent stale data on subsequent errors + unset _SILENT_FAILED_RC _SILENT_FAILED_CMD _SILENT_FAILED_LINE + fi + if [[ "$exit_code" -eq 0 ]]; then return 0 fi @@ -279,8 +289,12 @@ error_handler() { fi # Get active log file (BUILD_LOG or INSTALL_LOG) + # Prefer silent()'s logfile when available (contains the actual command output) local active_log="" - if declare -f get_active_logfile >/dev/null 2>&1; then + if [[ -n "${_SILENT_FAILED_LOG:-}" && -s "${_SILENT_FAILED_LOG}" ]]; then + active_log="$_SILENT_FAILED_LOG" + unset _SILENT_FAILED_LOG + elif declare -f get_active_logfile >/dev/null 2>&1; then active_log="$(get_active_logfile)" elif [[ -n "${SILENT_LOGFILE:-}" ]]; then active_log="$SILENT_LOGFILE" diff --git a/misc/vm-core.func b/misc/vm-core.func index f0d44cfa2..dd0595700 100644 --- a/misc/vm-core.func +++ b/misc/vm-core.func @@ -188,32 +188,18 @@ silent() { trap 'error_handler' ERR if [[ $rc -ne 0 ]]; then - # Source explain_exit_code if needed - if ! declare -f explain_exit_code >/dev/null 2>&1; then - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/error_handler.func) 2>/dev/null || true - fi + # Return instead of exit so that callers can use `$STD cmd || true` + # When no || is used, set -e + ERR trap catches it via error_handler() + export _SILENT_FAILED_RC="$rc" + export _SILENT_FAILED_CMD="$cmd" + export _SILENT_FAILED_LINE="$caller_line" + export _SILENT_FAILED_LOG="$logfile" - local explanation="" - if declare -f explain_exit_code >/dev/null 2>&1; then - explanation="$(explain_exit_code "$rc")" - fi - - printf "\e[?25h" - if [[ -n "$explanation" ]]; then - msg_error "in line ${caller_line}: exit code ${rc} (${explanation})" - else - msg_error "in line ${caller_line}: exit code ${rc}" - fi - msg_custom "→" "${YWB}" "${cmd}" - - if [[ -s "$logfile" ]]; then - echo -e "\n${TAB}--- Last 20 lines of log ---" - tail -n 20 "$logfile" - echo -e "${TAB}----------------------------\n" - fi - - exit "$rc" + return "$rc" fi + + # Clear stale flags on success + unset _SILENT_FAILED_RC _SILENT_FAILED_CMD _SILENT_FAILED_LINE _SILENT_FAILED_LOG 2>/dev/null || true } # ------------------------------------------------------------------------------