Commit 3209462
committed
Core: Fix crash when "bad thenable" is returned from global module hook
== Background
* We run QUnit.test functions via runTest() in src/test.js.
This includes both test.callback.call() and resolvePromise(),
and thus both are covered by the try-catch in test.run().
* We run (non-global) module hooks via callHook() in src/test.js,
which similarly does both, and both are covered by try-catch
in test.queueHook().
* We previously ran global module hooks with the resolvePromise()
not covered by try-catch. This means a bad thenable returned from
a global hook can cause a prettt confusing crash.
The ProcessingQueue gets interrupted, a global error is reported
(in the console only, not in the UI), the current test then
eventually times out, and the ProcessingQueue is unable to
continue because it is at non-zero config.depth, yet there are no
more top-level tests in the queue, which means advance() crashes
with advanceTestQueue() getting undefined from an empty array shift()
and trying to call it as a function.
== Fix
Fix global module hooks to also effectively do a try-catch. However,
I'm doing this in a bit of a different way to improve code quality.
There is an old TODO in the code from me that planned to actually
move the resolvePromise() outside the try-catch for consistency with
tests and global hooks. This is a bad idea, as it would spread this
bug to module hooks. I had that idea because I didn't realize that:
1. test.run() has a higher-level try-catch so it't actually global
hooks that is inconsistent, not module hooks.
2. There is nothing else saving us from a ProcessingQueue crash.
Yet, I still believe it is a good idea to move this outside the try-catch
because we should not tolerate errors from our internal resolvePromise
function. It is only the user-provided `promise.then` call inside
thqt function that we want to try-catch. A better way to achieve
this is to normalize the user-provided promise via Promise.resolve().
Our reference implementation in lib/ shows that it indeed try-catches
both the scheduling of then() callback, and the contents within.
So the way I'm fixing this is:
* Leave the global hooks code completely unchanged.
* Make test.run() and test.queueHook() more like queueGlobalHook,
by moving the resolvePromise outside the try-catch.
* Fix resolvePromise() to use Promise.resolve() which try-catches
just the user-provided "promise.then", nothing else is wrapped
in try-catch.1 parent 6f72eeb commit 3209462
File tree
3 files changed
+194
-68
lines changed- src
- test/cli/fixtures
3 files changed
+194
-68
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
| 180 | + | |
180 | 181 | | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
197 | 201 | | |
198 | 202 | | |
199 | 203 | | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
217 | 213 | | |
218 | 214 | | |
219 | 215 | | |
| |||
222 | 218 | | |
223 | 219 | | |
224 | 220 | | |
225 | | - | |
| 221 | + | |
226 | 222 | | |
227 | 223 | | |
228 | 224 | | |
229 | | - | |
230 | 225 | | |
231 | 226 | | |
232 | 227 | | |
| |||
244 | 239 | | |
245 | 240 | | |
246 | 241 | | |
247 | | - | |
248 | | - | |
| 242 | + | |
249 | 243 | | |
250 | 244 | | |
251 | 245 | | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
260 | | - | |
261 | | - | |
262 | | - | |
263 | 246 | | |
264 | 247 | | |
265 | 248 | | |
| |||
274 | 257 | | |
275 | 258 | | |
276 | 259 | | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
277 | 267 | | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
282 | | - | |
283 | | - | |
284 | | - | |
285 | | - | |
286 | | - | |
287 | | - | |
288 | | - | |
289 | | - | |
290 | | - | |
291 | | - | |
292 | | - | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
293 | 277 | | |
294 | | - | |
295 | 278 | | |
| 279 | + | |
| 280 | + | |
296 | 281 | | |
297 | 282 | | |
298 | 283 | | |
| |||
757 | 742 | | |
758 | 743 | | |
759 | 744 | | |
760 | | - | |
761 | | - | |
| 745 | + | |
762 | 746 | | |
763 | 747 | | |
764 | 748 | | |
765 | | - | |
| 749 | + | |
766 | 750 | | |
767 | 751 | | |
768 | 752 | | |
| |||
777 | 761 | | |
778 | 762 | | |
779 | 763 | | |
780 | | - | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
781 | 769 | | |
782 | 770 | | |
783 | 771 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
0 commit comments