Commit | Line | Data |
---|---|---|
78a1a75c | 1 | #!/bin/bash |
997eb0be IK |
2 | # Copyright 2018 Ian Kelling |
3 | ||
4 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | # you may not use this file except in compliance with the License. | |
6 | # You may obtain a copy of the License at | |
7 | ||
8 | # http://www.apache.org/licenses/LICENSE-2.0 | |
9 | ||
10 | # Unless required by applicable law or agreed to in writing, software | |
11 | # distributed under the License is distributed on an "AS IS" BASIS, | |
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | # See the License for the specific language governing permissions and | |
14 | # limitations under the License. | |
15 | ||
acd03e1e IK |
16 | |
17 | ||
18 | # Commentary: Bash stack trace and error handling functions. This file | |
19 | # is meant to be sourced. It loads some functions which you may want to | |
20 | # call manually (see the comments at the start of each one), and then | |
21 | # runs err-catch. See the README file for a slightly longer explanation. | |
22 | ||
997eb0be | 23 | err-allow() { |
acd03e1e IK |
24 | # help: turn off exit and stack trace on error. undoes err-catch |
25 | set +E +o pipefail; trap ERR | |
997eb0be IK |
26 | } |
27 | err-bash-trace() { | |
acd03e1e IK |
28 | # help: print stack trace |
29 | # | |
30 | # Note: It does not show function args unless you first run: | |
31 | # shopt -s extdebug | |
32 | # err-catch runs this for you. | |
33 | ||
34 | local -i argc_index=0 frame i start=${1:-1} max_indent=8 indent | |
35 | local source | |
36 | local extdebug=false | |
37 | if [[ $(shopt -p extdebug) == *-s* ]]; then | |
38 | extdebug=true | |
39 | fi | |
40 | for ((frame=0; frame < ${#FUNCNAME[@]}-1; frame++)); do | |
41 | argc=${BASH_ARGC[frame]} | |
42 | argc_index+=$argc | |
43 | ((frame < start)) && continue | |
44 | if (( ${#BASH_SOURCE[@]} > 1 )); then | |
45 | source="${BASH_SOURCE[frame+1]}:${BASH_LINENO[frame]}:" | |
46 | fi | |
47 | indent=$((frame-start+1)) | |
48 | indent=$((indent < max_indent ? indent : max_indent)) | |
49 | printf "%${indent}s↳%sin \`%s" '' "$source" "${FUNCNAME[frame]}" | |
50 | if $extdebug; then | |
51 | for ((i=argc_index-1; i >= argc_index-argc; i--)); do | |
52 | printf " %s" "${BASH_ARGV[i]}" | |
53 | done | |
78a1a75c | 54 | fi |
acd03e1e IK |
55 | echo \' |
56 | done | |
78a1a75c | 57 | } |
997eb0be | 58 | err-catch() { |
acd03e1e IK |
59 | # help: print stack trace and exit on error. |
60 | # | |
61 | # Set "${_errcatch_cleanup[@]}" to set a command which will run before exiting. | |
62 | # This function depends on err-bash-trace. | |
63 | ||
64 | set -E; shopt -s extdebug | |
65 | _err-trap() { | |
66 | err=$? | |
67 | exec >&2 | |
68 | set +x | |
69 | echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:in \`$BASH_COMMAND' returned $err" | |
70 | # err trap does not work within an error trap, the following line: | |
71 | err-bash-trace 2; set -e | |
72 | "${_errcatch_cleanup[@]}" | |
73 | echo "$0: exiting with code $err" | |
74 | exit $err | |
75 | } | |
76 | trap _err-trap ERR | |
77 | set -o pipefail | |
78a1a75c | 78 | } |
997eb0be | 79 | err-exit() { |
acd03e1e IK |
80 | # usage: err-exit [EXIT_CODE] [MESSAGE] |
81 | # help: exit and print stack trace. | |
82 | # | |
83 | # Use this instead of the exit command to be more informative. default | |
84 | # EXIT_CODE is 1. If only one of EXIT_CODE and MESSAGE is given, | |
85 | # we consider it to be an exit code if it is a number. | |
86 | # This function depends on err-bash-trace. | |
87 | ||
88 | exec >&2 | |
89 | code=1 | |
41be570a | 90 | if [[ "$*" ]]; then |
acd03e1e IK |
91 | if [[ ${1/[^0-9]/} == "$1" ]]; then |
92 | code=$1 | |
93 | if [[ $2 ]]; then | |
41be570a | 94 | printf '%s\n' "$2" |
acd03e1e IK |
95 | fi |
96 | else | |
41be570a | 97 | printf '%s\n' "$0: $1" |
78a1a75c | 98 | fi |
acd03e1e IK |
99 | fi |
100 | echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}" | |
101 | err-bash-trace 2 | |
102 | echo "$0: exiting with code $code" | |
103 | exit $err | |
78a1a75c | 104 | } |
acd03e1e | 105 | err-catch |