Page MenuHomePhabricator

When a proxy future wraps a future which throws an exception, resolve with an exception
ClosedPublic

Authored by epriestley on May 1 2020, 2:05 PM.
Tags
None
Referenced Files
F18985473: D21198.id50482.diff
Mon, Nov 17, 1:03 PM
F18858768: D21198.id.diff
Sat, Nov 1, 11:03 PM
F18854292: D21198.diff
Oct 31 2025, 11:06 PM
F18845540: D21198.id.diff
Oct 29 2025, 12:52 PM
F18816369: D21198.diff
Oct 21 2025, 6:23 AM
F18774268: D21198.id50482.diff
Oct 9 2025, 8:34 PM
F18739961: D21198.id.diff
Oct 1 2025, 11:42 PM
F18734281: D21198.id.diff
Sep 30 2025, 10:51 PM
Subscribers
None

Details

Summary

Ref T13528. When you call $future->resolve(), we currently guarantee it is resolved by calling FutureIterator->resolveAll().

resolveAll() does not actually "resolve()" futures: it guarantees that they are ready to "resolve()", but does not actually call "resolve()".

In particular, this means it does not throw exceptions.

This can lead to a case where a Future has "resolve()" called directly (e.g., via a FutureProxy), uses "FutureIterator" to resolve itself, throws an exception inside "FutureIterator", the exception is captured and attached to the Futuer, then the outer future tries to access results. This fails since it's out-of-order.

This can happen in practice with syntax highlighting futures, which may proxy pygments futures.

Instead, "resolveAll()" before testing for exaceptions.

Test Plan
  • Locally, tried to highlight a Paste with an unrecognized lexer extension using Pygments.
  • Before patch: fatal when trying to access results of a Future with no results (because it has an exception instead).
  • After patch: resolution throws the held exception properly.
  • (See also next change.)

Diff Detail

Repository
rARC Arcanist
Branch
future1
Lint
Lint Passed
Unit
Tests Passed
Build Status
Buildable 24297
Build 33471: Run Core Tests
Build 33470: arc lint + arc unit