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 line (_error)
78
79 # Note: myData co
80 try {
81 error 'bad' (code=99, myData={spam:'eggs'})
82 }
83 pp line (_error)
84
85 try {
86 error 'bad' (code=99, message='cannot override')
87 }
88 pp line (_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 '
282 }
283 echo code $[_error.code]
284 echo
285
286 try {
287 $SH -c '
288 assert (null)
289 echo "unreachable"
290 '
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 '
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 code 3
320
321 code 3
322
323 code 3
324
325 passed
326 code 0
327
328 ## END
329
330
331 #### assert on expressions
332
333 try {
334 $SH -c '
335 assert [true]
336 echo passed
337 '
338 }
339 echo code $[_error.code]
340 echo
341
342 try {
343 $SH -c '
344 func f() { return (false) }
345
346 assert [f()]
347 echo "unreachable"
348 '
349 }
350 echo code $[_error.code]
351 echo
352
353 try {
354 $SH -c '
355 assert [null]
356 echo "unreachable"
357 '
358 }
359 echo code $[_error.code]
360 echo
361
362 try {
363 $SH -c '
364 func f() { return (false) }
365
366 assert [true === f()]
367 echo "unreachable"
368 '
369 }
370 echo code $[_error.code]
371 echo
372
373 try {
374 $SH -c '
375 assert [42 === 42]
376 echo passed
377 '
378 }
379 echo code $[_error.code]
380 echo
381
382 ## STDOUT:
383 passed
384 code 0
385
386 code 3
387
388 code 3
389
390 code 3
391
392 passed
393 code 0
394
395 ## END
396
397
398 #### assert on expression that fails
399
400 try {
401 $SH -c '
402 assert [NAN === 1/0] # not true
403 echo unreachable
404 '
405 }
406 echo code $[_error.code]
407 echo
408
409 try {
410 $SH -c '
411 assert ["oof" === $(false)]
412 echo unreachable
413 '
414 }
415 echo code $[_error.code]
416 echo
417
418
419 ## STDOUT:
420 code 3
421
422 code 1
423
424 ## END
425
426 #### assert on chained comparison expression is not special
427
428 try {
429 $SH -c '
430 #pp line (42 === 42 === 43)
431 assert [42 === 42 === 43]
432 echo unreachable
433 '
434 }
435 echo code $[_error.code]
436 echo
437
438 ## STDOUT:
439 code 3
440
441 ## END