diff options
-rw-r--r-- | docs/error-handling.md | 30 | ||||
-rw-r--r-- | src/basic.bash | 15 |
2 files changed, 40 insertions, 5 deletions
diff --git a/docs/error-handling.md b/docs/error-handling.md index 483123f..27d8054 100644 --- a/docs/error-handling.md +++ b/docs/error-handling.md @@ -11,6 +11,11 @@ ## Limitations +### Introductory notes + +* Much of the below is from empirical evidence (aka testing). + + ### Backgrounded process * An error in a backgrounded process (e.g., `false &`) is ignored by the @@ -59,14 +64,35 @@ stack trace to be printed in the current [(sub-)](subshell.md)shell, but only a simple message mentioning the file and line number. * If there is no subshell involved, no stack trace is printed at all. - * Note that unset variable errors are also caught in - `declare var=$undef_var` (compare [Subshell section](#Subshell)). + * Note that unset variable errors are generally also caught in + `declare var=$undef_var` and `true $undef_var`. + * Compare [Subshell section](#Subshell). + * This does not hold if the shell is interactive (`bash -i`). * This is arguably not a big problem; such errors should mostly be quickly spotted by simple testing (or some static analysis tool). * Exceptions: Usage of `declare -n` and `eval` with dynamic variable names. +### Array variables + +* Attempting to assign `var[0]=(foo bar)` or `var['x']=(foo bar)` (where + `$var` is an array variable or associative array variable, respectively) + causes an error to be printed instead of a stack trace in the innermost + (sub-)shell. + * Compare behaviour of [unset variables](#Unset_variables). + * See also `src/basic.bash#errexit`. +* Attempting to assign `var['x']=foo` where `$var` is not an associative array + variable, has weird behaviour: + * In any case, the [(sub-)](subshell.md)shell where the error originally + occurs does not print a stacktrace, but a simple error message. + * If at least one subshell is involved, all but the lowest subshell print + a stack trace and all (sub-)shells exit correctly. + * If no subshell is involved, the error message is printed, but execution + is not aborted. + * Note that unlike for the preceding case, `set -o errexit` is irrelevant. + + ### Pipes * A pipeline is considered an error iff the last command returns non-zero. diff --git a/src/basic.bash b/src/basic.bash index a951e0c..a9d0a10 100644 --- a/src/basic.bash +++ b/src/basic.bash @@ -63,10 +63,19 @@ trap 'basic::print_stacktrace 0; exit 1' ERR # Inherit traps on ERR. set -o errtrace -# If we didn't trap ERR (and exit on ERR), we'd likely want the below. +# Exit on ERR. +# - This is mostly made redundant by the ERR trap (which causes an exit). +# - However, in some cases, the ERR trap does not apply, while `errexit` does: +# - `var[0]=(foo bar)`, when not in a subshell. +# - Same for an associative array. +# - It is unclear why `errexit` and the ERR trap apply on different +# conditions. +# - `inherit_errexit` seems indeed irrelevant in our case, but we enable it +# for consistency. # - Note: `inherit_errexit` is similar to `errtrace`. -#set -o errexit -#shopt -s inherit_errexit +# - See also: `/docs/error-handling.md#Array_variables` +set -o errexit +shopt -s inherit_errexit ## How to act on exit. |