Skip to content

Commit 4e83023

Browse files
committed
fix: Improve error handling in parse and rename fn to 'die'
1 parent 42bb57d commit 4e83023

File tree

6 files changed

+64
-57
lines changed

6 files changed

+64
-57
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ assert [ "$REPLY" = rho ]
5050
STATUS: IN DEVELOPMENT!
5151

5252
```sh
53-
# With bpm (highly recommended)
54-
bpm add hyperupcall/bash-object
53+
echo "dependencies [ 'hyperupcall/bash-object' ]" > 'bpm.toml'
54+
bpm install
5555
```
5656

5757
## TODO
5858
- do not auto create tree with set (or add -p flag that does so)
59-
- test errors on parser fail
6059
- workshop set-* functions
6160
- add support for set-object and set-array
6261
- error on invalid references (`type=object` in virtual object metadata, when it is referencing an array)

pkg/lib/parse.sh

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
# shellcheck shell=bash
22

3-
# TODO: Error handling
4-
# TODO: print column and 'mode' in error
5-
63
# @description Convert a user string into an array representing successive
74
# object / array access
85
# @exitcode 1 Miscellaneous error
96
# @exitcode 2 Parsing error
107
bash_object.parse_filter() {
8+
declare -ga REPLIES=()
9+
1110
local flag_parser_type=
1211

1312
for arg; do
@@ -25,12 +24,10 @@ bash_object.parse_filter() {
2524

2625
local filter="$1"
2726

28-
declare -ga REPLIES=()
29-
3027
if [ "$flag_parser_type" = 'simple' ]; then
3128
if [ "${filter::1}" != . ]; then
32-
printf '%s\n' "Error: bash-object: Filter must begin with a dot"
33-
return 2
29+
bash_object.util.die 'ERROR_INVALID_FILTER' 'Filter must begin with a dot'
30+
return
3431
fi
3532

3633
local old_ifs="$IFS"; IFS=.
@@ -66,16 +63,16 @@ bash_object.parse_filter() {
6663
if [ "$char" = . ]; then
6764
mode='MODE_EXPECTING_BRACKET'
6865
else
69-
printf '%s\n' "Error: bash-object: Filter must begin with a dot"
70-
return 2
66+
bash_object.util.die 'ERROR_INVALID_FILTER' 'Filter must begin with a dot'
67+
return
7168
fi
7269
;;
7370
MODE_BEFORE_DOT)
7471
if [ "$char" = . ]; then
7572
mode='MODE_EXPECTING_BRACKET'
7673
else
77-
printf '%s\n' "Error: bash-object: Each part in a filter must be deliminated by a dot"
78-
return 2
74+
bash_object.util.die 'ERROR_INVALID_FILTER' 'Each part in a filter must be deliminated by a dot'
75+
return
7976
fi
8077
;;
8178
MODE_EXPECTING_BRACKET)
@@ -84,8 +81,8 @@ bash_object.parse_filter() {
8481
elif [ "$char" = $'\n' ]; then
8582
return
8683
else
87-
printf '%s\n' "Error: bash-object: A dot MUST be followed by an opening bracket in this mode"
88-
return 2
84+
bash_object.util.die 'ERROR_INVALID_FILTER' 'A dot MUST be followed by an opening bracket in this mode'
85+
return
8986
fi
9087
;;
9188
MODE_EXPECTING_OPENING_STRING_OR_NUMBER)
@@ -94,17 +91,17 @@ bash_object.parse_filter() {
9491
if [ "$char" = \" ]; then
9592
mode='MODE_EXPECTING_STRING'
9693
elif [ "$char" = ']' ]; then
97-
printf '%s\n' "Error: bash-object: Key cannot be empty"
98-
return 2
94+
bash_object.util.die 'ERROR_INVALID_FILTER' 'Key cannot be empty'
95+
return
9996
else
10097
case "$char" in
10198
0|1|2|3|4|5|6|7|8|9)
10299
reply=$'\x1C'"$char"
103100
mode='MODE_EXPECTING_READ_NUMBER'
104101
;;
105102
*)
106-
printf '%s\n' "Error: bash-object: A number or opening quote must follow an open bracket"
107-
return 2
103+
bash_object.util.die 'ERROR_INVALID_FILTER' 'A number or opening quote must follow an open bracket'
104+
return
108105
;;
109106
esac
110107
fi
@@ -114,15 +111,15 @@ bash_object.parse_filter() {
114111
mode='MODE_STRING_ESCAPE_SEQUENCE'
115112
elif [ "$char" = \" ]; then
116113
if [ -z "$reply" ]; then
117-
printf '%s\n' "Error: bash-object: Key cannot be empty"
118-
return 2
114+
bash_object.util.die 'ERROR_INVALID_FILTER' 'Key cannot be empty'
115+
return
119116
fi
120117

121118
REPLIES+=("$reply")
122119
mode='MODE_EXPECTING_CLOSING_BRACKET'
123120
elif [ "$char" = $'\n' ]; then
124-
printf '%s\n' 'Filter is not complete'
125-
return 2
121+
bash_object.util.die 'ERROR_INVALID_FILTER' 'Filter is not complete'
122+
return
126123
else
127124
reply+="$char"
128125
fi
@@ -133,8 +130,8 @@ bash_object.parse_filter() {
133130
\") reply+=\" ;;
134131
']') reply+=']' ;;
135132
*)
136-
printf '%s\n' "Error: bash-object: Escape sequence of '$char' not valid"
137-
return 2
133+
bash_object.util.die 'ERROR_INVALID_FILTER' "Escape sequence of '$char' not valid"
134+
return
138135
;;
139136
esac
140137
mode='MODE_EXPECTING_STRING'
@@ -149,8 +146,8 @@ bash_object.parse_filter() {
149146
reply+="$char"
150147
;;
151148
*)
152-
printf '%s\n' "Error: bash-object: Expecting number, found '$char'"
153-
return 2
149+
bash_object.util.die 'ERROR_INVALID_FILTER' "Expecting number, found '$char'"
150+
return
154151
;;
155152
esac
156153
fi
@@ -159,15 +156,15 @@ bash_object.parse_filter() {
159156
if [ "$char" = ']' ]; then
160157
mode='MODE_BEFORE_DOT'
161158
else
162-
printf '%s\n' "Error: bash-object: Expected a closing bracket after the closing quotation mark"
163-
return 2
159+
bash_object.util.die 'ERROR_INVALID_FILTER' 'Expected a closing bracket after the closing quotation mark'
160+
return
164161
fi
165162
;;
166163
esac
167164
done <<< "$filter"
168165
else
169-
printf '%s\n' "bash-object: Must choose simple or advanced; no current default established"
170-
return 2
166+
bash_object.util.die 'ERROR_INVALID_ARGS' "Must pass either '--simple' or '--advanced'"
167+
return
171168
fi
172169
}
173170

pkg/lib/traverse-get.sh

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,18 @@ bash_object.traverse-get() {
6565
# case "$vmd_dtype" in
6666
# object)
6767
# if [ "$is_index_of_array" = yes ]; then
68-
# bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_VOBJ' "Expected object, but reference to array was found"
68+
# bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "Expected object, but reference to array was found"
6969
# return
7070
# fi
7171
# ;;
7272
# array)
7373
# if [ "$is_index_of_array" = no ]; then
74-
# bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_VOBJ' "Expected array, but reference to object was found"
74+
# bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "Expected array, but reference to object was found"
7575
# return
7676
# fi
7777
# ;;
7878
# *)
79-
# bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
79+
# bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
8080
# return
8181
# ;;
8282
# esac
@@ -92,18 +92,18 @@ bash_object.traverse-get() {
9292
done
9393
;;
9494
array)
95-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for object, but found existing array'
95+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for object, but found existing array'
9696
return
9797
;;
9898
*)
99-
bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
99+
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
100100
return
101101
;;
102102
esac
103103
elif [ "$final_value_type" = array ]; then
104104
case "$vmd_dtype" in
105105
object)
106-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for array, but found existing object'
106+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for array, but found existing object'
107107
return
108108
;;
109109
array)
@@ -112,26 +112,26 @@ bash_object.traverse-get() {
112112
REPLY=("${current_object[@]}")
113113
;;
114114
*)
115-
bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
115+
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
116116
return
117117
;;
118118
esac
119119
elif [ "$final_value_type" = string ]; then
120120
case "$vmd_dtype" in
121121
object)
122-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for string, but found existing object'
122+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for string, but found existing object'
123123
return
124124
;;
125125
array)
126-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for string, but found existing array'
126+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Queried for string, but found existing array'
127127
return
128128
;;
129129
*)
130-
bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
130+
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
131131
return
132132
esac
133133
else
134-
bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_PARAM' "final_value_type: $final_value_type"
134+
bash_object.util.die 'ERROR_INTERNAL_INVALID_PARAM' "final_value_type: $final_value_type"
135135
return
136136
fi
137137
fi
@@ -150,10 +150,10 @@ bash_object.traverse-get() {
150150
elif ((i+1 == ${#REPLIES[@]})); then
151151
local value="${current_object["$key"]}"
152152
if [ "$final_value_type" = object ]; then
153-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' "Queried for object, but found existing string '$value'"
153+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' "Queried for object, but found existing string '$value'"
154154
return
155155
elif [ "$final_value_type" = array ]; then
156-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' "Queried for array, but found existing string '$value'"
156+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' "Queried for array, but found existing string '$value'"
157157
return
158158
elif [ "$final_value_type" = string ]; then
159159
# shellcheck disable=SC2178

pkg/lib/traverse-set.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ bash_object.traverse-set() {
8888
elif [ "$final_value_type" = string ]; then
8989
current_object["$key"]="$final_value"
9090
else
91-
bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_PARAM' "final_value_type: $final_value_type"
91+
bash_object.util.die 'ERROR_INTERNAL_INVALID_PARAM' "final_value_type: $final_value_type"
9292
return
9393
fi
9494
fi
@@ -114,15 +114,15 @@ bash_object.traverse-set() {
114114
elif ((i+1 == ${#REPLIES[@]})); then
115115
case "$vmd_dtype" in
116116
object)
117-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' 'Was going to set-string, but found existing object'
117+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Was going to set-string, but found existing object'
118118
return
119119
;;
120120
array)
121-
bash_object.util.traverse_fail 'ERROR_VALUE_INCORRECT_TYPE' 'Was going to set-string, but found existing array'
121+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Was going to set-string, but found existing array'
122122
return
123123
;;
124124
*)
125-
bash_object.util.traverse_fail 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
125+
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "vmd_dtype: $vmd_dtype"
126126
return
127127
;;
128128
esac

pkg/lib/util/util.sh

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,40 @@
33
declare -gA ERRORS_BASH_OBJECT=(
44
[ERROR_VALUE_NOT_FOUND]='Attempted to access either a member of an object or an index of an array, but the member or index does not exist'
55
[ERROR_VALUE_INCORRECT_TYPE]='Attempted to get or set a value, but somewhere a value with a different type was expected'
6+
[ERROR_INVALID_FILTER]='The supplied filter is invalid'
7+
[ERROR_INVALID_ARGS]='Invalid arguments'
68
[ERROR_INTERNAL_INVALID_VOBJ]='Internal virtual object has incorrect metadata'
79
[ERROR_INTERNAL_INVALID_PARAM]='Internal parameter has an incorrect value'
10+
811
)
912

10-
bash_object.util.traverse_fail() {
13+
bash_object.util.die() {
1114
local error_key="$1"
12-
local error_context="$2"
13-
14-
if [ -z "$error_context" ]; then
15-
error_context='<empty>'
16-
fi
15+
local error_context="${2:-<empty>}"
1716

1817
local error_message="${ERRORS_BASH_OBJECT["$error_key"]}"
1918

2019
local error_output=
21-
printf -v error_output 'Failed to perform object operation:
20+
case "$error_key" in
21+
ERROR_INVALID_FILTER)
22+
printf -v error_output 'Failed to perform operation:
23+
-> code: %s
24+
-> message: %s
25+
-> context: %s
26+
-> PARSER_COLUMN_NUMBER: %s' "$error_key" "$error_message" "$error_context" "$PARSER_COLUMN_NUMBER"
27+
;;
28+
*)
29+
printf -v error_output 'Failed to parse filter:
2230
-> code: %s
2331
-> message: %s
2432
-> context: %s' "$error_key" "$error_message" "$error_context"
33+
;;
34+
esac
2535

2636
printf '%s' "$error_output"
2737
return 2
2838
}
39+
2940
# TODO
3041
stdtrace.log() {
3142
local level="$1"

tests/parse-filter-advanced.bats

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ load './util/init.sh'
5555
run bash_object.parse_filter -a '.[""'
5656

5757
assert_failure
58-
assert_line -p "Error: bash-object: Key cannot be empty"
58+
assert_line -p "Key cannot be empty"
5959
}
6060

6161
@test "advanced errors on incomplete 4" {

0 commit comments

Comments
 (0)