From c43346aa352f1d2e2d08045e58726b664cc28eea Mon Sep 17 00:00:00 2001 From: ge Date: Sun, 15 May 2022 07:19:12 +0300 Subject: [PATCH] feat: Add error handling --- src/lib/common.sh | 87 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/src/lib/common.sh b/src/lib/common.sh index f1ce463..6498b13 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -30,24 +30,91 @@ log() { log_file="$__log_file" - # If no arguments passed OR '0' descriptor is open, then read from descriptor. - # If no arguments AND '0' descriptor is closed, then 'message' will not be set. - [[ "$#" == 0 || -t 0 ]] || message="$(cat <&0)" + # Read message from STDIN if args not passed. + [[ ! -t 0 ]] || [[ "$#" == 0 ]] && message="$(cat <&0)" # Set log date format - [ -n "$log_date_fmt" ] || log_date_fmt='%d/%b/%Y:%H:%M:%S %z' + [ "$log_date_fmt" ] || log_date_fmt='%d/%b/%Y:%H:%M:%S %z' while (( "$#" )); do case "$1" in - -p|--print) print=1; shift;; - -) message="$(cat <&0)"; shift "$#";; - *) message="$@"; shift "$#";; + -p) print=1; shift;; + -) message="$(cat <&0)"; shift "$#";; + *) message="$*"; shift "$#";; esac done - [[ "$print" == 1 ]] && echo "$message" + [[ "$print" == 1 ]] && echo -e "$message" - while read line; do - printf '[%s] [%s] %s\n' "$(date +"$log_date_fmt")" "$0" "$line" >> "$log_file" + while read -r line; do + if [[ "$line" ]]; then + printf '[%s] [%s] %s\n' "$(date +"$log_date_fmt")" "$0" "$line" >> "$log_file" + fi done <<< "$(sed -r 's/\x1B\[(([0-9]+)(;[0-9]+)*)?[m,K,H,f,J]//g' <<< "$message")" } + +err() { + # Handle error. Print errors to STDERR, log, process + # and exit from script. + # + # Usage: err [-eao] MESSAGE + + local message + local errexit + local errappend + local onerr + + [[ ! -t 0 ]] || [[ "$#" == 0 ]] && message="$(cat <&0)" + + # Split combined short options, e.g. '-abc' to '-a' '-b' '-c' + for args in "$@"; do + shift + case "$args" in + -*) + args="$(echo "${args:1}" | grep -o . | xargs -I {} echo -n '-{} ')" + set -- "$@" $args;; + *) + set -- "$@" "$args";; # save positional arguments + esac + done + + while (( "$#" )); do + case "$1" in + -e) errexit=1; shift;; + -a) errappend=1; shift;; + -o) onerr=1; shift;; + -) message="$(cat <&0)"; shift "$#";; + *) message="$*"; shift "$#";; + esac + done + + log "$message" + echo -e "$message" >&2 + [ "$errappend" ] && errors+=("$message") + + # Run user defined function on_error() + if [ "$onerr" ]; then + if is_function_set on_error; then + on_error + fi + fi + + # Exit + if [ "$errexit" ]; then + log "Backup ERROR: Exiting with previous errors"; exit 1 + fi +} + +try() { + # Commands wrapper for error handling + # + # Usage: try COMMAND + + if eval "$@" 2>> "$__log_file"; then + return 0 # Success + else + err -a "Error: Something went wrong when executing command:" + err -a " $*" + err -aeo "Check $__log_file log for details." + fi +}