Created SC2249 (markdown)

Vidar Holen
2019-04-14 16:55:38 -07:00
parent 2f61243c64
commit d9d1d4d9a5

70
SC2249.md Normal file

@@ -0,0 +1,70 @@
## Consider adding a default *) case, even if it just exits with error.
### Problematic code:
```sh
case "$1" in
start) start_service ;;
stop) stop_service ;;
restart|reload|force-reload)
stop_service;
start_service;;
esac
```
### Correct code:
```sh
case "$1" in
start) start_service ;;
stop) stop_service ;;
restart|reload|force-reload)
stop_service;
start_service;;
*)
echo >&2 "Invalid choice: $1"
exit 1
esac
```
### Rationale:
ShellCheck found a `case` statement that may not be considering all possible cases. This may mean that only the [happy paths](https://en.wikipedia.org/wiki/Happy_path) are accounted for.
Consider adding a default case to handle other values. If you don't know what to do or don't believe it'll ever happen, exiting with an error is good, fail-fast practice.
The example is adapted from a real world Debian init script, which due to a missing default case reports success on any misspelled command (here with underscore instead of dash):
```
$ /etc/init.d/screen-cleanup force_reload && echo success
success
```
### Exceptions:
This suggestion only triggers in verbose mode (`-S verbose`).
If you don't have a default case because the default should be to take no action, consider adding a comment to other humans:
```
case "$(uname)" in
CYGWIN*) cygwin=1;;
MINGW*) mingw=1;;
*) # No special workarounds identified
esac
```
If you believe that it's impossible for the expression to have any other value, it's considered good practice to add the equivalent of an `assert(0)` to fail fast if this assumption should turn out to be incorrect in the current or future versions:
```
case "$result" in
true) proceed;;
false) cancel;;
*) echo >&2 "Submit bug report: '$result' should be true or false."
exit 127
esac
```
### Related resources:
* Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc!