From 71a283e0f599b5b3cae545fee38b523191d4f4bb Mon Sep 17 00:00:00 2001 From: fatalerrors Date: Thu, 17 Jun 2021 18:28:03 +0200 Subject: [PATCH] preliminary support for error management --- init.sh | 11 ++++- lib/aaa_errors.sh | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 lib/aaa_errors.sh diff --git a/init.sh b/init.sh index 9eaa1e6..e555663 100755 --- a/init.sh +++ b/init.sh @@ -2,6 +2,15 @@ # Init : initialise une machine et la met en conformité # Copyright (c) 2021 Geoffray Levasseur +# trace ERR through pipes +set -o pipefail + +# trace ERR through 'time command' and other functions +set -o errtrace + +# set -e : exit the script if any statement returns a non-true return value +set -o errexit + export VERSION="0.95.1" # Stocke le chemin du script @@ -120,5 +129,5 @@ install_mk-agent conf_syslog conf_mail -echo "That's all folks !" +prnt I "That's all folks !" echo "Après vérification des logs, il est recommandé de redémarrer la machine..." diff --git a/lib/aaa_errors.sh b/lib/aaa_errors.sh new file mode 100644 index 0000000..fe190a7 --- /dev/null +++ b/lib/aaa_errors.sh @@ -0,0 +1,121 @@ +# Error management functions + +function exit_handler() +{ + local error_code="$?" + + [[ $error_code == 0 ]] && return; + + # Local variables + local i=0 + local regex='' + local mem='' + + local error_file='' + local error_lineno='' + + local lineno='' + + + # Print error header + prnt E "${BIWhite}*** ${BIRed}Une erreur fatale est intervenue, \ + le script va s'arrêter prématurément !$DEFAULTCOL" + + # Getting backtrace + _backtrace=$( backtrace 2 ) + + + # MANAGING THE OUTPUT: + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # + + regex='^([a-z]{1,}) ([0-9]{1,})$' + + if [[ $error_lineno =~ $regex ]]; then + + # The error line was found on the log + # (e.g. type 'ff' without quotes wherever) + # -------------------------------------------------------------- + local row="${BASH_REMATCH[1]}" + lineno="${BASH_REMATCH[2]}" + + echo -e "Fichier :\t\t${error_file}" + echo -e "${row} :\t\t${lineno}\n" + + echo -e "Code d'erreur :\t${error_code}" + else + regex="^${error_file}\$|^${error_file}\s+|\s+${error_file}\s+|\s+${error_file}\$" + if [[ "$_backtrace" =~ $regex ]]; then + + # The file was found on the log but not the error line + # (could not reproduce this case so far) + # ------------------------------------------------------ + echo -e "Fichier :\t\t$error_file" + echo -e "Code d'ereur :\t${error_code}" + else + # The error file is the first on backtrace list: + + # Exploding backtrace on newlines + mem=$IFS + IFS="\n" + IFS=${IFS:0:1} + local lines=( $_backtrace ) + IFS=$mem + + error_file="" + if [[ -n "${lines[1]}" ]]; then + array=( ${lines[1]} ) + + for (( i=2; i<${#array[@]}; i++ )); do + error_file="$error_file ${array[$i]}" + done + + # Trim + error_file="$( echo "$error_file" | + sed -e 's/^[ \t]*//' | + sed -e 's/[ \t]*$//' )" + fi + + echo -e "Fichier :\t\t$error_file" + echo -e "Colonne :\t\tunknown\n" + + echo -e "Code d'erreur :\t${error_code}" + fi + fi + + # Print the backtrace + echo -e "\n$_backtrace\n" + + # Exit the script + prnt E "Sortie !" + + exit "$error_code" +} +trap exit_handler EXIT # ! ! ! TRAP EXIT ! ! ! +trap exit ERR # ! ! ! TRAP ERR ! ! ! + + +# Print a backtrace +function backtrace +{ + local _start_from_=0 + + local params=( "$@" ) + if (( "${#params[@]}" >= "1" )); then + _start_from_="$1" + fi + + local i=0 + local first=false + local last=false + while caller $i > /dev/null; do + if [[ -n "$_start_from_" ]] && (( "$i" + 1 >= "$_start_from_" )); then + if [[ "$first" == false ]]; then + echo "==== Pile d'appel ====" + first=true + fi + caller $i + fi + (( i=i++ )) + done +} +export -f backtrace