Browse Source

on_return

main
pvincent 2 weeks ago
parent
commit
4525f3e558
  1. 50
      poc
  2. 24
      test/stub/scenario.bash

50
poc

@ -49,6 +49,18 @@ function is_true {
function miaou_debug { function miaou_debug {
is_true "${MIAOU_DEBUG}" && >&4 builtin echo -e "\e[90m <== DEBUG ==> \e[33m$*\e[0m" || true is_true "${MIAOU_DEBUG}" && >&4 builtin echo -e "\e[90m <== DEBUG ==> \e[33m$*\e[0m" || true
} }
function on_return {
local regex='return ([0-9]+)'
if [[ "$BASH_COMMAND" =~ $regex ]] && [[ "${BASH_REMATCH[1]}" -gt 0 ]]; then
failure_code="${BASH_REMATCH[1]}"
failure_type="RETURN"
failure_payload="${FUNCNAME[0]}"
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}"
miaou_debug "<on_return code=$failure_code payload=$failure_payload />"
fi
}
# overridden function which permits backtracing of the original `exit` statement # overridden function which permits backtracing of the original `exit` statement
function exit { function exit {
error_source=("${BASH_SOURCE[@]}") error_source=("${BASH_SOURCE[@]}")
@ -89,13 +101,22 @@ function print_miaou_error {
} }
function on_error { function on_error {
trap - RETURN
failure_code="${1:-200}" failure_code="${1:-200}"
>&4 printf '\r' # TODO: force carriage return explicitly, is it really useful? >&4 printf '\r' # TODO: force carriage return explicitly, is it really useful?
if [[ $$ == "$BASHPID" ]]; then if [[ $$ == "$BASHPID" ]]; then
miaou_debug "<on_error exit=$failure_code/>"
if [[ ! -v failure_type ]]; then
failure_type="COMMAND_ERROR" failure_type="COMMAND_ERROR"
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" '...'
failure_payload="${BASH_COMMAND}"
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}"
fi
if [[ -v failure_payload ]]; then
miaou_debug "<on_error exit=$failure_code type=${failure_type} payload=${failure_payload} />"
else
miaou_debug "<on_error exit=$failure_code type=${failure_type} />"
fi
error_source=("${BASH_SOURCE[@]}") error_source=("${BASH_SOURCE[@]}")
error_lineno=("${BASH_LINENO[@]}") error_lineno=("${BASH_LINENO[@]}")
@ -116,6 +137,7 @@ function on_error {
} }
function on_pipe { function on_pipe {
trap - RETURN
local tmp_error regex source lineno local tmp_error regex source lineno
error_source=("${BASH_SOURCE[@]}") error_source=("${BASH_SOURCE[@]}")
@ -198,14 +220,28 @@ function dump_stacktrace {
} }
function on_exit { function on_exit {
local code
code="${1:-0}"
trap - RETURN
local code="${1:-0}" last_error regex
mapfile -t tmp_error <"$MIAOU_BASH_ERROR" mapfile -t tmp_error <"$MIAOU_BASH_ERROR"
2>&3 >&3 dump_stderr 2>&3 >&3 dump_stderr
if [[ -v failure_type && "$failure_type" == 'RETURN' ]]; then
last_error="${tmp_error[-1]}"
regex='^(.*): line ([0-9]+): miaou_error: code=[0-9]+ type=RETURN'
if [[ "$last_error" =~ $regex ]]; then
miaou_debug "<return exit=$code />"
local source line
source="${BASH_REMATCH[1]}"
line="${BASH_REMATCH[2]}"
error_source=("$source" "${error_source[@]}")
error_lineno=("$line" "${error_lineno[@]}")
error_funcname=("$failure_payload" "${error_funcname[@]}")
else
miaou_debug "<return type=unexpected />"
fi
else
if [[ $code -gt 0 && ${#tmp_error[@]} -gt 0 ]]; then if [[ $code -gt 0 && ${#tmp_error[@]} -gt 0 ]]; then
local last_error regex
last_error="${tmp_error[-1]}" last_error="${tmp_error[-1]}"
miaou_debug "<on_exit exit=$code last_error='$last_error'>" miaou_debug "<on_exit exit=$code last_error='$last_error'>"
if [[ $code -eq 1 ]]; then if [[ $code -eq 1 ]]; then
@ -230,6 +266,7 @@ function on_exit {
error_funcname=("${error_funcname[@]}" '<main>') error_funcname=("${error_funcname[@]}" '<main>')
fi fi
fi fi
fi
miaou_debug "</on_exit>" miaou_debug "</on_exit>"
fi fi
@ -245,7 +282,7 @@ function on_exit {
set -euo pipefail set -euo pipefail
set -E # HALT on subshell error set -E # HALT on subshell error
# set -T # DEBUG RETURN
set -T # DEBUG RETURN
[[ $# -lt 1 ]] && >&2 echo 'ERROR: script expected!' && builtin exit 1 [[ $# -lt 1 ]] && >&2 echo 'ERROR: script expected!' && builtin exit 1
BASH_ARGV0="$1" && shift # to pretend script runs by itself BASH_ARGV0="$1" && shift # to pretend script runs by itself
@ -253,6 +290,7 @@ BASH_ARGV0="$1" && shift # to pretend script runs by itself
trap 'on_error $?' ERR trap 'on_error $?' ERR
trap 'on_exit $?' EXIT trap 'on_exit $?' EXIT
trap 'on_pipe' PIPE trap 'on_pipe' PIPE
trap 'on_return' RETURN
if [[ -e /proc/$$/fd/3 ]]; then exec 4>&3 3>&-; else exec 4>/dev/tty; fi # swap fd 3 4 when fd 3 sent off if [[ -e /proc/$$/fd/3 ]]; then exec 4>&3 3>&-; else exec 4>/dev/tty; fi # swap fd 3 4 when fd 3 sent off
exec 3>/dev/stderr 2>"$MIAOU_BASH_ERROR" exec 3>/dev/stderr 2>"$MIAOU_BASH_ERROR"

24
test/stub/scenario.bash

@ -33,11 +33,6 @@ function do_last_false {
! true ! true
} }
function do_return {
echo START
return 99
}
function do_command_not_found { function do_command_not_found {
echo START echo START
command_not_found A B C command_not_found A B C
@ -50,6 +45,10 @@ function do_exit {
echo SHOULD NOT APPEAR echo SHOULD NOT APPEAR
} }
function do_return {
should_return
}
function do_unbound_associative { function do_unbound_associative {
declare -A associative declare -A associative
associative['A']='Abc' associative['A']='Abc'
@ -115,6 +114,10 @@ function call_function_which_will_exit {
exit 99 exit 99
} }
function call_function_which_will_return {
return 199
}
function F2 { function F2 {
echo "stdout A" echo "stdout A"
# echo toto >>/tmp/toto # echo toto >>/tmp/toto
@ -155,6 +158,17 @@ function main {
>&2 echo some trace in stderr2 >&2 echo some trace in stderr2
} }
function should_return {
echo A
if call_function_which_will_return; then
echo SUCCESS
else
echo FAILURE
fi
call_function_which_will_return
echo SHOULD NOT APPEAR
}
function F3 { function F3 {
echo F3 echo F3
return 0 return 0

Loading…
Cancel
Save