OILS / spec / ysh-builtin-error.test.sh View on Github | oilshell.org

436 lines, 214 significant
1# spec/ysh-builtin-error
2
3## our_shell: ysh
4
5#### User errors behave like builtin errors
6func divide(a, b) {
7 if (b === 0) {
8 error 'divide by zero' (code=3)
9 }
10
11 return (a / b)
12}
13
14# errors can be caught with try
15try { = divide(42, 0) }
16echo status=$_status
17
18= divide(42, 0)
19
20## status: 3
21## STDOUT:
22status=3
23## END
24
25#### _error register is initially empty dict
26
27echo $[type(_error)]
28echo $[len(_error)]
29
30## STDOUT:
31Dict
320
33## END
34
35#### error builtin sets _error.message, which can be used by programs
36
37func divide(a, b) {
38 if (b === 0) {
39 error "divide by zero: $a / $b" (code=3)
40 }
41 return (a / b)
42}
43
44try { = divide(42, 0) }
45echo status=$_status
46echo message=$[_error.message]
47
48proc p {
49 echo $[divide(5, 0)]
50}
51
52try { p }
53echo status=$_status
54echo message=$[_error.message]
55
56## STDOUT:
57status=3
58message=divide by zero: 42 / 0
59status=3
60message=divide by zero: 5 / 0
61## END
62
63#### error builtin adds named args as properties on _error Dict
64
65try {
66 error 'bad' (code=99)
67}
68pp test_ (_error)
69
70# Note: myData co
71try {
72 error 'bad' (code=99, myData={spam:'eggs'})
73}
74pp test_ (_error)
75
76try {
77 error 'bad' (code=99, message='cannot override')
78}
79pp test_ (_error)
80
81## STDOUT:
82(Dict) {"code":99,"message":"bad"}
83(Dict) {"myData":{"spam":"eggs"},"code":99,"message":"bad"}
84(Dict) {"message":"bad","code":99}
85## END
86
87#### Errors within multiple functions
88func inverse(x) {
89 if (x === 0) {
90 error '0 does not have an inverse' # default status is 1
91 }
92
93 return (1 / x)
94}
95
96func invertList(list) {
97 var result = []
98 for item in (list) {
99 call result->append(inverse(item))
100 }
101 return (result)
102}
103
104= invertList([1, 2, 0])
105## status: 10
106## STDOUT:
107## END
108
109#### Impact of errors on var declaration
110func alwaysError() {
111 error "it's an error" (status=100)
112}
113
114try {
115 var mylist = [1 + 2, alwaysError()]
116
117 echo this will never be printed
118}
119= mylist # undefined! status becomes 1
120## status: 1
121## STDOUT:
122## END
123
124#### default error code is 10
125error 'some error'
126## status: 10
127## STDOUT:
128## END
129
130#### error code should be an integer
131error 'error' (code='a string?')
132## status: 3
133## STDOUT:
134## END
135
136#### Error code should be named arg, not positional
137error msg (100)
138## status: 3
139## STDOUT:
140## END
141
142#### error cannot take word args
143error uh-oh ('error', status=1)
144## status: 3
145## STDOUT:
146## END
147
148#### error requires arguments
149error
150## status: 2
151## STDOUT:
152## END
153
154#### error cannot have a code of 0
155error ('error', code=0)
156## status: 2
157## STDOUT:
158## END
159
160#### try { error oops }
161
162try { error oops }
163echo status=$_status
164
165## STDOUT:
166status=10
167## END
168
169#### Handle _error.code
170
171proc failing {
172 error 'failed' (code=99)
173}
174
175try {
176 failing
177}
178if (_error.code === 99) {
179 echo PASS
180}
181
182try {
183 failing
184}
185case (_error.code) {
186 (0) { echo success }
187 (1) { echo one }
188 (else) { echo CASE PASS }
189}
190
191## STDOUT:
192PASS
193CASE PASS
194## END
195
196
197#### failed builtin usage
198
199set +o errexit
200
201try { echo ok }
202
203failed (42)
204echo status=$?
205
206try { echo ok }
207
208# Too many args
209failed a b
210echo status=$?
211
212## STDOUT:
213ok
214status=2
215ok
216status=2
217## END
218
219#### failed builtin
220
221try {
222 echo hi
223}
224if failed {
225 echo 'should not get here'
226} else {
227 echo 'ok 1'
228}
229
230try {
231 #test -n ''
232
233 # Hm json read sets the regular error
234 # Should we raise error.Structured?
235 #json read <<< '{'
236
237 var x = fromJson('{')
238
239 # Hm the error is in a SUBPROCESS HERE
240 #echo '{' | json read
241}
242if failed {
243 echo 'ok 2'
244} else {
245 echo 'should not get here'
246}
247
248## STDOUT:
249hi
250ok 1
251ok 2
252## END
253
254
255#### assert on values
256
257try {
258 $SH -c '
259 assert (true)
260 echo passed
261 '
262}
263echo code $[_error.code]
264echo
265
266try {
267 $SH -c '
268 func f() { return (false) }
269
270 assert (f())
271 echo "unreachable"
272 ' | grep -v Value
273}
274echo code $[_error.code]
275echo
276
277try {
278 $SH -c '
279 assert (null)
280 echo "unreachable"
281 ' | grep -v Value
282}
283echo code $[_error.code]
284echo
285
286try {
287 $SH -c '
288 func f() { return (false) }
289
290 assert (true === f())
291 echo "unreachable"
292 ' | grep -v Value
293}
294echo code $[_error.code]
295echo
296
297try {
298 $SH -c '
299 assert (42 === 42)
300 echo passed
301 '
302}
303echo code $[_error.code]
304echo
305
306## STDOUT:
307passed
308code 0
309
310
311code 3
312
313
314code 3
315
316
317code 3
318
319passed
320code 0
321
322## END
323
324
325#### assert on expressions
326
327try {
328 $SH -c '
329 assert [true]
330 echo passed
331 '
332}
333echo code $[_error.code]
334echo
335
336try {
337 $SH -c '
338 func f() { return (false) }
339
340 assert [f()]
341 echo "unreachable"
342 '
343}
344echo code $[_error.code]
345echo
346
347try {
348 $SH -c '
349 assert [null]
350 echo "unreachable"
351 '
352}
353echo code $[_error.code]
354echo
355
356try {
357 $SH -c '
358 func f() { return (false) }
359
360 assert [true === f()]
361 echo "unreachable"
362 ' | grep -v '(Bool)'
363}
364echo code $[_error.code]
365echo
366
367try {
368 $SH -c '
369 assert [42 === 42]
370 echo passed
371 '
372}
373echo code $[_error.code]
374echo
375
376## STDOUT:
377passed
378code 0
379
380code 3
381
382code 3
383
384
385code 3
386
387passed
388code 0
389
390## END
391
392
393#### assert on expression that fails
394
395try {
396 $SH -c '
397 assert [NAN === 1/0] # not true
398 echo unreachable
399 '
400}
401echo code $[_error.code]
402echo
403
404try {
405 $SH -c '
406 assert ["oof" === $(false)]
407 echo unreachable
408 '
409}
410echo code $[_error.code]
411echo
412
413
414## STDOUT:
415code 3
416
417code 1
418
419## END
420
421#### assert on chained comparison expression is not special
422
423try {
424 $SH -c '
425 #pp test_ (42 === 42 === 43)
426 assert [42 === 42 === 43]
427 echo unreachable
428 '
429}
430echo code $[_error.code]
431echo
432
433## STDOUT:
434code 3
435
436## END