on_return
This commit is contained in:
@@ -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,36 +220,51 @@ function dump_stacktrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function on_exit {
|
function on_exit {
|
||||||
local code
|
trap - RETURN
|
||||||
code="${1:-0}"
|
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
|
||||||
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'>"
|
regex='^(.*): line ([0-9]+): miaou_error: code=[0-9]+ type=RETURN'
|
||||||
if [[ $code -eq 1 ]]; then
|
if [[ "$last_error" =~ $regex ]]; then
|
||||||
regex='^(.*): line ([0-9]+): (.*): unbound variable$'
|
miaou_debug "<return exit=$code />"
|
||||||
if [[ "$last_error" =~ $regex ]]; then
|
local source line
|
||||||
local source line payload
|
source="${BASH_REMATCH[1]}"
|
||||||
source="${BASH_REMATCH[1]}"
|
line="${BASH_REMATCH[2]}"
|
||||||
line="${BASH_REMATCH[2]}"
|
error_source=("$source" "${error_source[@]}")
|
||||||
payload="${BASH_REMATCH[3]}"
|
error_lineno=("$line" "${error_lineno[@]}")
|
||||||
miaou_debug "<unbound_variable source=${source} line=${line} payload=${payload}>"
|
error_funcname=("$failure_payload" "${error_funcname[@]}")
|
||||||
failure_code=$code
|
else
|
||||||
failure_type='UNBOUND_VARIABLE'
|
miaou_debug "<return type=unexpected />"
|
||||||
failure_payload="${BASH_REMATCH[3]}"
|
fi
|
||||||
error_source=("${BASH_SOURCE[@]}")
|
|
||||||
error_lineno=("${BASH_LINENO[@]}")
|
else
|
||||||
error_funcname=("${FUNCNAME[@]}")
|
if [[ $code -gt 0 && ${#tmp_error[@]} -gt 0 ]]; then
|
||||||
unset 'error_source[0]' 'error_lineno[0]' 'error_funcname[0]'
|
last_error="${tmp_error[-1]}"
|
||||||
unset 'error_source[-1]' 'error_lineno[-1]' 'error_funcname[-1]'
|
miaou_debug "<on_exit exit=$code last_error='$last_error'>"
|
||||||
unset 'error_source[-1]' 'error_lineno[-1]' 'error_funcname[-1]'
|
if [[ $code -eq 1 ]]; then
|
||||||
error_source=("$source" "${error_source[@]}")
|
regex='^(.*): line ([0-9]+): (.*): unbound variable$'
|
||||||
error_lineno=("$line" "${error_lineno[@]}")
|
if [[ "$last_error" =~ $regex ]]; then
|
||||||
error_funcname=("${error_funcname[@]}" '<main>')
|
local source line payload
|
||||||
|
source="${BASH_REMATCH[1]}"
|
||||||
|
line="${BASH_REMATCH[2]}"
|
||||||
|
payload="${BASH_REMATCH[3]}"
|
||||||
|
miaou_debug "<unbound_variable source=${source} line=${line} payload=${payload}>"
|
||||||
|
failure_code=$code
|
||||||
|
failure_type='UNBOUND_VARIABLE'
|
||||||
|
failure_payload="${BASH_REMATCH[3]}"
|
||||||
|
error_source=("${BASH_SOURCE[@]}")
|
||||||
|
error_lineno=("${BASH_LINENO[@]}")
|
||||||
|
error_funcname=("${FUNCNAME[@]}")
|
||||||
|
unset 'error_source[0]' 'error_lineno[0]' 'error_funcname[0]'
|
||||||
|
unset 'error_source[-1]' 'error_lineno[-1]' 'error_funcname[-1]'
|
||||||
|
unset 'error_source[-1]' 'error_lineno[-1]' 'error_funcname[-1]'
|
||||||
|
error_source=("$source" "${error_source[@]}")
|
||||||
|
error_lineno=("$line" "${error_lineno[@]}")
|
||||||
|
error_funcname=("${error_funcname[@]}" '<main>')
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
miaou_debug "</on_exit>"
|
miaou_debug "</on_exit>"
|
||||||
@@ -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"
|
||||||
|
|||||||
+19
-5
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user