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