diff --git a/bin/miaou-bash b/bin/miaou-bash index 02747ee..d18e27b 100755 --- a/bin/miaou-bash +++ b/bin/miaou-bash @@ -48,6 +48,7 @@ function is_true { # example: alias toto="bash -c \"[[ \\\$MIAOU_DEBUG == 'true' ]] && echo yes \\\$* || echo nope\"" function miaou_debug { if is_true "${MIAOU_DEBUG}"; then + local saved_bash_rematch=("${BASH_REMATCH[@]}") # important when regex are used before calling miaou_debug local i message="$*" padding='' local compute_hierarchy=true [[ ! -v miaou_debug_hierarchy ]] && miaou_debug_hierarchy=0 @@ -66,6 +67,7 @@ function miaou_debug { [[ "${message}" =~ $regex ]] && miaou_debug_hierarchy=$((miaou_debug_hierarchy + 1)) || true + BASH_REMATCH=("${saved_bash_rematch[@]}") # important when regex are used before calling miaou_debug fi } @@ -165,12 +167,52 @@ function on_error { failure_type='FILE_NOT_FOUND' failure_payload="${BASH_REMATCH[3]}" miaou_debug "" - else - miaou_debug "" - regex='^[[:space:]]*miaou_trace: ' - if [[ "$last_error" =~ $regex ]]; then - miaou_debug "" - #TODO: .. + + elif ! is_true "$CHILD_PROCESS"; then + # in main process only, not from children! + local regex2 + last_error="${tmp_error[-1]}" + regex2='^[[:space:]]+miaou_trace: source=(.*) lineno=(.*) funcname=(.*)$' + if [[ "$last_error" =~ $regex2 ]]; then + trace_source="${BASH_REMATCH[1]}" + trace_lineno="${BASH_REMATCH[2]}" + trace_funcname="${BASH_REMATCH[3]}" + extra_source=("$trace_source") + extra_lineno=("$trace_lineno") + extra_funcname=("$trace_funcname") + miaou_debug "" + # go backward + for ((i = ${#tmp_error[@]} - 2; i >= 0; i--)); do + content=${tmp_error[$i]} + miaou_debug "" + if [[ "$content" =~ $regex2 ]]; then + source="${BASH_REMATCH[1]}" + lineno="${BASH_REMATCH[2]}" + funcname="${BASH_REMATCH[3]}" + extra_source=("$source" "${extra_source[@]}") + extra_lineno=("$lineno" "${extra_lineno[@]}") + extra_funcname=("$funcname" "${extra_funcname[@]}") + miaou_debug '' + else + regex2='^(.*): line ([0-9]+): miaou_error: (.*) [0-9]+(.*)$' + if [[ "$content" =~ $regex2 ]]; then + failure_type='CHILD_ERROR' + failure_payload="${BASH_REMATCH[3]}" + local optional_payload + optional_payload="${BASH_REMATCH[4]}" + [[ -n "$optional_payload" ]] && + optional_payload="${optional_payload# payload: }" && + failure_payload="${failure_payload} ${optional_payload}" + miaou_debug "" + else + miaou_debug '' + fi + break + fi + miaou_debug '' + done + miaou_debug "" + miaou_debug "" fi fi fi @@ -185,9 +227,16 @@ function on_error { unset 'error_source[-1]' 'error_lineno[-1]' 'error_funcname[-1]' unset 'error_source[0]' 'error_lineno[-1]' 'error_funcname[0]' error_funcname[-1]='
' - error_source=("${error_source[@]}") - error_lineno=("${error_lineno[@]}") - error_funcname=("${error_funcname[@]}") + + if [[ $failure_type == 'CHILD_ERROR' ]]; then + error_source=("${extra_source[@]}" "${error_source[@]}") + error_lineno=("${extra_lineno[@]}" "${error_lineno[@]}") + error_funcname=("${extra_funcname[@]}" "${error_funcname[@]}") + else + error_source=("${error_source[@]}") + error_lineno=("${error_lineno[@]}") + error_funcname=("${error_funcname[@]}") + fi if [[ -v failure_payload ]]; then miaou_debug "" @@ -414,6 +463,11 @@ function on_exit { add_miaou_error "${BASH_SOURCE[2]}" "${BASH_LINENO[1]}" "${failure_code}" "${failure_type}" "${failure_payload}" miaou_debug "" + elif [[ -v failure_type && "$failure_type" == 'CHILD_ERROR' ]]; then + for ((i = 0; i < ${#extra_source[@]}; i++)); do unset 'tmp_error[-1]'; done + add_miaou_error "${BASH_SOURCE[2]}" "${BASH_LINENO[1]}" "${failure_code}" "${failure_type}" "${failure_payload}" + miaou_debug "" + elif [[ ! -v failure_type ]]; then if [[ $failure_code -gt 0 && ${#tmp_error[@]} -gt 0 ]]; then last_error="${tmp_error[-1]}" diff --git a/doc/index.md b/doc/index.md index da40b8c..2b53121 100644 --- a/doc/index.md +++ b/doc/index.md @@ -36,3 +36,4 @@ count=0 count=0 count=$((count+1)) ``` + diff --git a/test/miaou-bash.test.bash b/test/miaou-bash.test.bash index 2d052af..db022ee 100755 --- a/test/miaou-bash.test.bash +++ b/test/miaou-bash.test.bash @@ -21,7 +21,6 @@ function fail_type { local success regex hint_message success=false hint_message="${3:-}" - # mapfile -t stderr <<<"$(source ./test/stub/scenario.bash "$1" 2>&1 >/dev/null 3>/dev/null)" mapfile -t stderr <<<"$(miaou-bash ./test/stub/scenario.bash "$1" 2>&1 >/dev/null 3>/dev/null)" last_error="${stderr[-1]}" diff --git a/test/stub/extra/onemore.bash b/test/stub/extra/onemore.bash index 72de6de..435dbdf 100755 --- a/test/stub/extra/onemore.bash +++ b/test/stub/extra/onemore.bash @@ -9,11 +9,11 @@ function onemore { function do_next { echo do_next - command_not_found + echo $nope + exit 10 # youpi grep nope nope + command_not_found exit - exit 10 # youpi - echo $nope return 7 return }