Score:1

Ajax form inside custom system.404 route controller doesn't work

in flag

I need to display custom logic in 404 pages so I have overridden the route controller of the system.404 route like this:

class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('system.404')) {
      $route->setDefault('_controller', '\Drupal\mymodule\Controller\myController::on404');
    }
  }
}

So let's say I am currently at the path /non-existing-path and the on404 callback renders my custom content just fine. Problem is I am also rendering a form that contains an Ajax element (a button), which doesn't work because apparently the Ajax request is made towards the following path:

/system/404?q=non-existing-path&destination=non-existing-path&_exception_statuscode=404&ajax_form=1&_wrapper_format=drupal_ajax

which, not unexpectedly, returns a Status Code: 404 Not Found

What am I missing?

--

So far I've tried intercepting the NotFoundHttpException with my own listener and changing it to a HttpException(200) in hopes I could turn a 404 page into a 200 but I am at a loss after that and it seems like an overkill.

4uk4 avatar
cn flag
If you want to try to change the 404 to a 200 set a redirect response in the event listener.
Chris Roditis avatar
in flag
thanks but this will redirect me to another path, I want to stay at the current path (that doesn't exist) and render my content together with the ajax form
4uk4 avatar
cn flag
OK, then I misread your last sentence. Concerning the main topic. `/system/404` doesn't return a 404 status code when used outside of an exception. It returns the content of system.404 in a 200 response and it works with Ajax. Just tested it by setting a form as 404 content.
Chris Roditis avatar
in flag
Thanks for looking into it but to make it more clear, I am trying to render a form (with an ajax button in it), in the default 404 page. So whenever someone hits a non existent page, the "Page not found" message appears and below it the form. Problem is the ajax button doesnt work.
4uk4 avatar
cn flag
As explained, I can't reproduce the issue. The system/404 route returns a 200 (not a 404 as you've mentioned) and Ajax actions over this route work without problems in my tests with two different forms, a custom form and a core form (node edit form).
Chris Roditis avatar
in flag
The path Im concerned with is not system/404, but any random non-existent path. Therefore I'm concerned with the call of the 'system.404' route *within* the NotFoundHttpException exception, not outside of one. Only when a 404 Not found is thrown.
4uk4 avatar
cn flag
I have placed both test forms in a 404 of a random non-existent path as well. Cause for concern are the subsequent requests for system/404, which in my case return a status code 200 and in your case a status code 404, which I can't reproduce.
Score:0
cn flag

Ajax form inside custom system.404 route controller does work

For example a node form returned from the controller:

<?php

namespace Drupal\mymodule\Controller;    

use Drupal\node\Entity\Node;

class MyController extends ControllerBase {

  public function on404() {
    $node = Node::create(['type' => 'article']);
    return $this->entityFormBuilder()->getForm($node);
  }

}

The node form is fully functional including complex Ajax operations like opening the media browser.

Status code 404 or 200

Problem is I am also rendering a form that contains an Ajax element (a button), which doesn't work because apparently the Ajax request is made towards the following path:

/system/404?q=non-existing-path&destination=non-existing-path&_exception_statuscode=404&ajax_form=1&_wrapper_format=drupal_ajax

which, not unexpectedly, returns a Status Code: 404 Not Found

This is not true, a request for /system/404 returns a 200 status code when called outside of an exception handler, for example in an ajax request. The system.404 route is a normal route which is executed by the exception handler in a sub-request. The 404 status is added later and not part of this route.

Chris Roditis avatar
in flag
"The system.404 route is a normal route which is executed by the exception handler in a sub-request" this helped point me in the right direction. Thanks for all the help!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.