0

I have a very simple custom block/form that takes a user id and jumps to their profile page. The form submitForm has this:

$uid = $form_state->getValue('uid');
$path = '/user/' . $uid;
$response = new RedirectResponse(Url::fromUserInput($path)->toString());
$response->send();

This works as expected on my local dev system and on our staging server. For some reason, it does not work on the production site (different server but same configuration as the staging server, afaik).

There are no errors. The page does do a page load but stays on the same page.

I have added a log point to capture the response object. It is identical on both the prod site and the staging site.

The only thing I have seen in the past which appears similar to this (a page load with no errors but simply fails to do anything) is from Apache mod_security. Hosting company assures me it is not mod_security.

Any thoughts on something which could cause this or how to further debug the issue?

1 Answer 1

4

Never send a response in custom Drupal code. You can add it to $form_state when submitting a form:

$form_state->setResponse($response);

Why you can't send a response?

Answering the last comment. The Drupal kernel is stacked. Each layer returns a response for the request it receives. If one layer sends response headers prematurely, this will not stop the process of building the real response also sent to the client. It's unpredictable how a platform reacts to this unclear situation. In your dev environment the browser is directly connected to the web server and what you see is that it reacts on the first redirect headers received. But this can change in production ...

If you want to alter the response returned by Drupal then it's probably the best idea to use your own layer in form of a middleware. See this great answer https://drupal.stackexchange.com/a/303653/47547

However, if you can use the Symfony/Drupal API, like in this case the Form API, there is no need for that. See https://drupal.stackexchange.com/a/304037/47547

7
  • Still not sure why my sending the reponse worked everywhere except the production server; but setResponse does work. Thank you.
    – liquidcms
    Commented Jan 1 at 22:36
  • See drupal.stackexchange.com/a/304037/47547
    – 4uk4
    Commented Jan 1 at 23:59
  • Tried to clean up some other code using "the correct approach". Have a controller where i changed return value to this: return $this->redirect('node.add', ['node_type' => $node_type], ['query' => $query]); and it simply refreshes the page i am currently on. Adding ->send() to the end makes it redirect to the correct url. Hmm.
    – liquidcms
    Commented Jan 2 at 14:12
  • There are 48 hits when I check Drupal for return $this->redirect(), and none of them sends the response.
    – 4uk4
    Commented Jan 2 at 14:21
  • @liquidcms git grep --fixed-strings '$this->redirect(' shows many lines similar to return $this->redirect('search.view_' . $entity->id()); and some of them are in controller classes that extend ControllerBase, but none of them calls send() in the object returned from redirect().
    – avpaderno
    Commented Jan 2 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.