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
|