diff --git a/bin/miaou-bash b/bin/miaou-bash index 4baa463..8833d30 100755 --- a/bin/miaou-bash +++ b/bin/miaou-bash @@ -19,11 +19,12 @@ function on_return { fi } -# overridden function which permits backtracing of original `return` statement +# overridden function which permits backtracing of original `exit` statement function exit { code=${1:-0} # >&2 echo "${BASH_SOURCE[2]}: line ${BASH_LINENO[0]}: exit $@" >&2 echo "${BASH_SOURCE[2]}:${BASH_LINENO[0]} exit $code" + debug "overridden exit $code" builtin exit "$code" } @@ -34,15 +35,20 @@ function on_exit { stack_functions=("${FUNCNAME[@]}") stack_sources=("${BASH_SOURCE[@]}") + # >/dev/tty echo "stack_functionsA ${#stack_functions[@]} ${stack_functions[@]}" + unset 'stack_lines[-1]' unset 'stack_lines[-1]' unset 'stack_functions[0]' unset 'stack_functions[-1]' - stack_functions[-1]='
' + + # >/dev/tty echo "stack_functionsB ${#stack_functions[@]} ${stack_functions[@]}" + [[ "${#stack_functions[@]}" -gt 0 ]] && stack_functions[-1]='
' + unset 'stack_sources[0]' unset 'stack_sources[-1]' - if [[ "${stack_functions[1]}" == exit && "${stack_sources[1]}" == "${BASH_SOURCE[0]}" ]]; then + if [[ "${#stack_functions[@]}" -gt 1 && "${stack_functions[1]}" == exit && "${stack_sources[1]}" == "${BASH_SOURCE[0]}" ]]; then # the exit case scenario unset 'stack_functions[1]' unset 'stack_sources[1]' @@ -57,6 +63,8 @@ function on_exit { failure_payload='' if [[ $code -gt 0 ]]; then + + [[ -p /dev/stdout ]] && debug "kill pipe $code !" && >&2 echo "pipe error: original status $code" && kill -SIGPIPE $$ last_error=$(tail -n1 "$MIAOU_BASH_ERROR") last_source=${stack_sources[0]} last_source=${last_source//./"\."} # replace '.' with '\.' @@ -100,10 +108,19 @@ function on_exit { if [[ $code == 1 ]]; then failure_type='SOURCE NOT FOUND' stack_lines[0]=$line + code=128 # change code to 128 to remember this embedded 'source not found' issue! else if [[ $code == 127 ]]; then failure_type='FILE NOT FOUND' - # TODO: print a warning hint in stderr like so: prefer source rather than subshell + regex='\.sh$|\.bash$' + if [[ "$failure_payload" =~ $regex ]]; then + stack_functions[0]="${stack_functions[0]} (hint: prefer source than subshell:1)" + code=129 # change code to 128 to remember this embedded 'source not found' issue! + # >&2 echo "${last_error}" + else + : + # >&2 echo "${last_error}" + fi else failure_type='UNKNOWN NOT FOUND' fi @@ -118,10 +135,22 @@ function on_exit { fi fi else - failure_type='COMMAND' + failure_type='UNDEFINED' failure_payload="${last_error}" regex="^ .*:[0-9]* .*\$" - [[ "$last_error" =~ $regex ]] || failure_traces+=("ERROR $code:") # + if [[ "$last_error" =~ $regex ]]; then + if [[ "${code}" == 128 ]]; then + failure_type='SUBSHELL SOURCE NOT FOUND' + stack_functions[0]="${stack_functions[0]} (hint: prefer source than subshell:2)" + fi + else + regex='^pipe error:' + if [[ "$last_error" =~ $regex ]]; then + code=141 + failure_type='PIPE ERROR' + fi + failure_traces+=("ERROR $code:") # + fi fi for i in "${!stack_functions[@]}"; do @@ -129,22 +158,32 @@ function on_exit { failure_traces+=("$stack_detail") done dump_failure + # builtin exit "$code" else dump_success fi - builtin exit "$code" } +function debug { + $MIAOU_BASH_DEBUG && >/dev/tty echo "*********** DEBUG: $@" + true +} + function dump_failure { dump_stderr true - $MIAOU_BASH_DEBUG && >/dev/tty echo '---stacktrace---' - >&4 echo "CODE: ${code}" - >&4 echo "TYPE: ${failure_type}" - >&4 echo "PAYLOAD: ${failure_payload}" + debug '---stacktrace---' + if [[ ${failure_type} == 'SUBSHELL SOURCE NOT FOUND' ]]; then + : + else + >&4 echo "CODE: ${code}" + >&4 echo "TYPE: ${failure_type}" + >&4 echo "PAYLOAD: ${failure_payload}" + fi for i in "${failure_traces[@]}"; do >&4 echo -e "$i" done + debug '---end of stacktrace---' cleanup } @@ -166,7 +205,7 @@ function dump_success { } function cleanup { - trap - ERR TERM INT EXIT + trap - ERR TERM EXIT DEBUG exec 3>&- 4>&- rm "$MIAOU_BASH_ERROR" }