On Wed, Apr 29, 2026, at 9:30 AM, Rob Landers wrote:
> On Wed, Apr 22, 2026, at 20:28, Larry Garfield wrote:
>> I think a key question to answer here is: Do we care to differentiate
>> between CM errors and underlying errors?
>
> I don't think we need to differentiate at the CM level. Suppression is
> a policy decision that belongs to the caller, not the context manager.
> The CM's job is cleanup: rollback the transaction, close the file,
> release the lock, etc. Whether the exception continues propagating
> after that is the caller's call, and `try using` already provides
> exactly that:
>
> try using ($db->transaction() => $conn) {
> $conn->execute('INSERT INTO orders ...');
> } catch (ValidationException $e) {
> // Caller chooses to suppress this here
> }
>
> That makes `exitContext()` simple: return void, do your cleanup, and
> get out. If cleanup fails, it throws naturally, and the desugared form
> can chain the original exception as `$previous` so the root cause isn't
> lost. If the caller wants to suppress or differentiate, they already
> have `try using` for exactly that.
>
> It's worth noting that every example in the RFC (database transactions,
> file locks, error handler swaps, async scopes) does cleanup and
> propagates. None of them actually need the power to suppress. If a
> context manager wants to give callers a clean exception hierarchy to
> catch against, it can wrap underlying exceptions in their own types
> during cleanup. That's just normal exception design, no special syntax
> required.
>
> — Rob
Just to make sure I'm following you, you're arguing that a CM should not have
any way at all to suppress an exception? I don't think I'd agree with that,
personally. Even if it's a rare case, I do believe it's a feature that should
remain.
--Larry Garfield