Problem/Motivation
Even thought the how redirection is solved in RemotePostWebformHandler is aligned with an old
change record β
that explains how redirection should be solved when "Redirecting when not in context of a controller" it is does not working properly anymore. (Maybe it has this unexpected side effect since Drupal 9.2 when Session management changed:
https://www.drupal.org/node/3006306 β
)
When a Webform uses the built-in Remote post handler and..
* the "Custom error response redirect URL" is configured
* and "Use AJAX" feature is disabled on the Webform
* the remote post (API call) fails for any reasons
then the following error gets logged every time
RuntimeException: Failed to start the session because headers have already been sent by "endor/symfony/http-foundation/Response.php" at line 368. in Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() (line 152 of endor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php)
When "Use AjAX" feature is enabled, there is no error like this.
I have also attached a modified Webform Contact form as a POC (exported via Features).
Steps to reproduce
Proposed resolution
Probably the good-old "Redirecting when not in context of a controller" is not working anymore. A simple and clean solution could be throwing a special exception instead in this layer and catching that with a \Symfony\Component\HttpKernel\KernelEvents::EXCEPTION
subscriber and performing the redirection there.
Fun fact, Drupal core already has a similar solution in place that in the context of the Form API is considered an unwanted solution/technical dept:
#2367555: Deprecate EnforcedResponseException support β
.
Related classes:
* https://github.com/drupal/core/blob/10.1.2/lib/Drupal/Core/Form/Enforced...
* https://github.com/drupal/core/blob/10.1.2/lib/Drupal/Core/EventSubscrib...
(This solution does not warrant that the exception subscriber only acts on HTML requests!)
This approach could work but it would still generate another noise in the logs, since the remote post handler is called from an entity storage post save hook, therefore when an exception is thrown in that layer it gets automatically logged. We would probably need a workaround for that too and ignore the special "WebformRedirectAfterFailedRemotePostException".
Remaining tasks
User interface changes
API changes
Data model changes