Note: I created the issue and code with the help of AI, everything is reviewed and checked.

Problem

`CanvasFormatter::build()` wraps `$items->toRenderable()` in
`catch (\Throwable)` and logs the exception away. `FormBuilder` throws
`FormAjaxException` on **every** AJAX form request — it is the flow-control
signal `FormAjaxSubscriber::onException()` turns into the AJAX response. Canvas
deliberately lets it through
(`RenderSafeComponentContainer::renderComponent()`, `ComponentTreeItemList`),
and the formatter one layer up then catches and drops it.

So a form rendered inside a canvas_page never gets an AJAX response: on
a webform `managed_file` upload silently did nothing, and submitting
produced *"File upload in progress. Uploaded file may be lost."*. Watchdog shows
it as `Canvas rendering failed for entity canvas_page/: ` with an empty
message — `FormAjaxException` has no message.

Fix

Rethrow `EnforcedResponseException`, `FormAjaxException` and
`HttpExceptionInterface` before the generic `catch (\Throwable)`, mirroring what
Canvas itself does one layer down. Genuine rendering errors are still logged and
swallowed.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

fago created an issue. See original summary.

fago’s picture

Issue summary: View changes

fago’s picture

Status: Active » Needs review
fago’s picture

  • fago committed 01ceeac4 on 3.x
    fix: #3618933 CanvasFormatter swallows flow-control exceptions
    
    By: fago
    
fago’s picture

Status: Needs review » Fixed

this works well, is fully tested and code is good. merged.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.