1 # spec/ysh-builtin-error
2
3 ## our_shell: ysh
4 ## oils_failures_allowed: 0
5
6 #### try expects an argument
7
8 try
9 echo status=$?
10
11 ## status: 3
12 ## STDOUT:
13 ## END
14
15 #### User errors behave like builtin errors
16 func divide(a, b) {
17 if (b === 0) {
18 error 'divide by zero' (status=3)
19 }
20
21 return (a / b)
22 }
23
24 # errors can be caught with try
25 try { = divide(42, 0) }
26 echo status=$_status
27
28 = divide(42, 0) # sets status to 3
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 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" (status=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 # Design bug: this isn't caught!
66
67 # try echo $[divide(3, 0]
68
69 ## STDOUT:
70 status=3
71 message=divide by zero: 42 / 0
72 status=3
73 message=divide by zero: 5 / 0
74 ## END
75
76 #### error builtin adds named args as properties on _error Dict
77
78 try {
79 error 'bad' (status=99)
80 }
81 pp line (_error)
82
83 # Note: myData co
84 try {
85 error 'bad' (status=99, myData={spam:'eggs'})
86 }
87 pp line (_error)
88
89 try {
90 error 'bad' (status=99, message='cannot override')
91 }
92 pp line (_error)
93
94 ## STDOUT:
95 (Dict) {"status":99,"message":"bad"}
96 (Dict) {"myData":{"spam":"eggs"},"status":99,"message":"bad"}
97 (Dict) {"message":"bad","status":99}
98 ## END
99
100 #### Errors within multiple functions
101 func inverse(x) {
102 if (x === 0) {
103 error '0 does not have an inverse' # default status is 1
104 }
105
106 return (1 / x)
107 }
108
109 func invertList(list) {
110 var result = []
111 for item in (list) {
112 call result->append(inverse(item))
113 }
114 return (result)
115 }
116
117 = invertList([1, 2, 0])
118 ## status: 10
119 ## STDOUT:
120 ## END
121
122 #### Impact of errors on var declaration
123 func alwaysError() {
124 error "it's an error" (status=100)
125 }
126
127 try {
128 var mylist = [1 + 2, alwaysError()]
129
130 echo this will never be printed
131 }
132 = mylist # undefined! status becomes 1
133 ## status: 1
134 ## STDOUT:
135 ## END
136
137 #### Error defaults status to 10
138 error 'some error'
139 ## status: 10
140 ## STDOUT:
141 ## END
142
143 #### Error expects an int status
144 error 'error' (status='a string?')
145 ## status: 3
146 ## STDOUT:
147 ## END
148
149 #### Error typed arg, not named arg
150 error msg (100)
151 ## status: 3
152 ## STDOUT:
153 ## END
154
155 #### Errors cannot take command args
156 error uh-oh ('error', status=1)
157 ## status: 3
158 ## STDOUT:
159 ## END
160
161 #### Error must take arguments
162 error
163 ## status: 2
164 ## STDOUT:
165 ## END
166
167 #### Errors cannot have a status of 0
168 error ('error', status=0)
169 ## status: 2
170 ## STDOUT:
171 ## END
172
173 #### try { error oops }
174
175 try { error oops }
176 echo status=$_status
177
178 ## STDOUT:
179 status=10
180 ## END