From: Ian Kelling Date: Mon, 27 Jan 2020 23:47:39 +0000 (-0500) Subject: handle pipestatus, add some todos X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=b4d7f86af736f8e417c7a2c16ac0ce6924236641;p=errhandle.git handle pipestatus, add some todos --- diff --git a/README b/README index 23af1dd..e23ff99 100644 --- a/README +++ b/README @@ -1 +1,2 @@ -Read the err file next to this one. +Todo: populate this readme even though +the full manual is in the err file. diff --git a/err b/err index dc1a218..ccdffee 100644 --- a/err +++ b/err @@ -6,6 +6,11 @@ # functions below for for more details and manual error handling. See # end of file for credits etc. +# TODO: investigate to see if we can format output betting in case of +# subshell failure. Right now, we get independent trace from inside and +# outside of the subshell. Note, errexit + inherit_errexit doesn't have +# any smarts around this either. + ####################################### # err-catch: Setup trap on ERR to print stack trace and exit (or return # if the shell is interactive). This is the most common use case so we @@ -39,9 +44,11 @@ err-catch() { ) fi declare -i _err_func_last=0 - shopt -s extdebug + if [[ $- != *c* ]]; then + shopt -s extdebug + fi # shellcheck disable=SC2154 - trap '_err-bash-trace-interactive $? "$BASH_COMMAND" ${BASH_ARGC[0]} "${BASH_ARGV[@]}" || return $?' ERR + trap '_err-bash-trace-interactive $? "${PIPESTATUS[*]}" "$BASH_COMMAND" ${BASH_ARGC[0]} "${BASH_ARGV[@]}" || return $?' ERR else # Man bash on exdebug: "If set at shell invocation, arrange to # execute the debugger". We want to avoid that, but I want this file @@ -86,9 +93,13 @@ err-allow() { # ####################################### err-exit() { - local err=$? + local err=$? pipestatus="${PIPESTATUS[*]}" + # This has to come before most things or vars get changed local msg="${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $err" + if [[ $pipestatus != "$err" ]]; then + msg+=", PIPESTATUS: $pipestatus" + fi set +x if [[ $1 == -* ]]; then err=${1#-} @@ -176,14 +187,20 @@ _err-bash-trace-interactive() { # We have these passed to us because they are lost inside the # function. ret=$1 - bash_command="$2" - argc=$(( $3 - 1 )) - shift 3 + pipestatus="$2" + bash_command="$3" + argc=$(( $4 - 1 )) + shift 4 argv=("$@") # The trap returns a nonzero, then gets called again. This condition - # tells us if we are the first. - if (( _err_func_last > last )); then - printf "ERR: \`%s\' returned %s\n" "$bash_command" $ret >&2 + # tells us if is that has happened by checking if we've gone down a + # stack level. + if (( _err_func_last >= last )); then + printf "ERR: \`%s\' returned %s" "$bash_command" $ret >&2 + if [[ $pipestatus != "$ret" ]]; then + printf ", PIPESTATUS: %s" "$pipestatus" >&2 + fi + echo >&2 fi printf " from \`%s" "${FUNCNAME[1]}" >&2 if shopt extdebug >/dev/null; then