246042d28c1241dd91ea03ddd3415f8ab20d3bbc
2 # Copyright (C) 2019 Ian Kelling
3 # SPDX-License-Identifier: AGPL-3.0-or-later
5 # meant to be sourced. copy/pasted from https://iankelling.org/git/?p=errhandle;a=summary
7 # Commentary: Bash stack trace and error handling functions. This file
8 # is meant to be sourced. It loads some functions which you may want to
9 # call manually (see the comments at the start of each one), and then
10 # runs err-catch. See the README file for a slightly longer explanation.
13 #######################################
16 # usage: err-bash-trace [MESSAGE]
18 # This function is called by the other functions which print stack
21 # It does not show function args unless you first run:
23 # which err-catch & err-print do for you.
25 # MESSAGE Message to print just before the stack trace.
27 # _frame_start Optional variable to set before calling. The frame to
28 # start printing on. default=1. Useful when printing from
29 # an ERR trap function to avoid printing that function.
30 #######################################
32 local -i argc_index
=0 frame i start
=${_frame_start:-1}
37 for ((frame
=0; frame
< ${#FUNCNAME[@]}; frame
++)); do
38 argc
=${BASH_ARGC[frame]}
40 ((frame
< start
)) && continue
41 if (( ${#BASH_SOURCE[@]} > 1 )); then
42 source="${BASH_SOURCE[frame]}:${BASH_LINENO[frame-1]}:"
44 printf " from %sin \`%s" "$source" "${FUNCNAME[frame]}"
45 if shopt extdebug
>/dev
/null
; then
46 for ((i
=argc_index-1
; i
>= argc_index-argc
; i--
)); do
47 printf " %s" "${BASH_ARGV[i]}"
55 #######################################
56 # On error print stack trace and exit
59 # errcatch-cleanup If set, this command will run just before exiting.
60 #######################################
62 set -E; shopt -s extdebug
67 local msg
="${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $err"
68 if (( ${#FUNCNAME[@]} > 2 )); then
74 set -e # err trap does not work within an error trap
75 if type -t errcatch-cleanup
>/dev
/null
; then
78 echo "$0: exiting with status $err"
86 #######################################
87 # For interactive shells: on error, print stack trace and return
90 # err_catch_ignore Array containing glob patterns to test against filenames to ignore
91 # errors from. Initialized to ignore bash-completion scripts on debian
93 # _err_func_last Used internally.
94 # _err_catch_err Used internally.
95 # _err_catch_i Used internally.
96 # _err_catch_ignore Used internally.
98 # misc: All shellcheck disables for this function are false positives.
99 #######################################
100 # shellcheck disable=SC2120
101 err-catch-interactive
() {
103 '/etc/bash_completion.d/*'
105 # shellcheck disable=SC2034
106 declare -i _err_func_last
=0
107 set -E; shopt -s extdebug
108 # shellcheck disable=SC2154
109 trap '_err_catch_err=$? _trap_bc="$BASH_COMMAND"
110 _err_catch_ignore=false
111 for _err_catch_i in "${err_catch_ignore[@]}"; do
112 if [[ ${BASH_SOURCE[0]} == $_err_catch_i ]]; then
113 _err_catch_ignore=true
117 if ! $_err_catch_ignore; then
118 if (( ${#FUNCNAME[@]} > _err_func_last )); then
119 echo ERR: \`$_trap_bc'"\'"' returned $_err_catch_err
121 _err_func_last=${#FUNCNAME[@]}
122 if (( _err_func_last )); then
123 printf " from %s:%s:in \`%s" "${BASH_SOURCE[0]}" "$(declare -F "${FUNCNAME[0]}"|awk "{print \$2}")" "${FUNCNAME[0]}"
124 if shopt extdebug >/dev/null; then
125 for ((_err_catch_i=${BASH_ARGC[0]}-1; _err_catch_i >= 0; _err_catch_i--)); do
126 printf " %s" "${BASH_ARGV[_err_catch_i]}"
130 return $_err_catch_err
137 #######################################
138 # Undoes err-catch/err-catch-interactive
139 #######################################
146 #######################################
147 # On error, print stack trace
148 #######################################
150 # help: on errors: print stack trace
152 # This function depends on err-bash-trace.
154 set -E; shopt -s extdebug
159 echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $err"
167 #######################################
168 # Print stack trace and exit
170 # Use this instead of the exit command to be more informative.
172 # usage: err-exit [EXIT_CODE] [MESSAGE]
174 # EXIT_CODE Default is 1.
175 # MESSAGE Print MESSAGE to stderr. If only one of EXIT_CODE
176 # and MESSAGE is given, we consider it to be an
177 # exit code if it is a number.
178 #######################################
183 if [[ ${1/[^0-9]/} == "$1" ]]; then
186 printf '%s\n' "$2" >&2
189 printf '%s\n' "$0: $1" >&2
192 echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}"
194 echo "$0: exiting with code $code"
198 # We want this more often than not, so run it now.
199 if [[ $
- == *i
* ]]; then
200 err-catch-interactive