|
|
|
@ -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]='<main>' |
|
|
|
|
|
|
|
# >/dev/tty echo "stack_functionsB ${#stack_functions[@]} ${stack_functions[@]}" |
|
|
|
[[ "${#stack_functions[@]}" -gt 0 ]] && stack_functions[-1]='<main>' |
|
|
|
|
|
|
|
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:") # <undefined> |
|
|
|
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:") # <undefined> |
|
|
|
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" |
|
|
|
} |
|
|
|
|