Sometimes not possible to vote 'The specified #ajax callback is empty or not callable'

Created on 11 February 2022, over 2 years ago
Updated 3 January 2024, 6 months ago

I don't sure how to reproduce this issue, however, our clients report an error when they use VPN.
I have a look into the module and found a place responds on this 'callback' => '::ajaxReplaceForm'.
Going to provide a solution.

🐛 Bug report
Status

Needs work

Version

1.0

Component

User interface

Created by

🇺🇦Ukraine Ruslan Piskarov Kiev, Ukraine

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇮🇳India nitesh624 Ranchi, India

    Tried the steps mentioned in #5 but not able to reproduce

  • 🇮🇳India nitesh624 Ranchi, India

    This issue seems to be intermittent.

  • 🇮🇳India nitesh624 Ranchi, India

    So I spent few days to get the steps to reproduce this issue

    • I spin up a D10 site in https://simplytest with poll module
    • I have allowed anonymous voting
    • I am connected to VPN on my system
    • Not I Visited the poll url on chrome browser, I was able to vote
    • Now I changed the network on my system and reconnected the vpn
    • Now I visited the poll page on Chrome browser I am getting vote results
    • Now I visited the poll page on Edge browser
    • Then I am getting poll form and on clicking the vote button i am getting ajax error
    • "Symfony\Component\HttpKernel\Exception\HttpException: The specified #ajax callback is empty or not callable. in Drupal\Core\Form\FormAjaxResponseBuilder->buildResponse() (line 67 of /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php).
    • But When I cleared the drupal cache. the poll paeg shows the vote results
  • 🇮🇳India nitesh624 Ranchi, India

    But if I add
    $form['#cache]['max-age] = 0; in the src/Form/PollViewForm.php file line 114 before the return $form statement. The issue is no longer coming up.
    So I assume something

  • 🇮🇳India nitesh624 Ranchi, India

    ivnish are you able to reproduce this issue?

  • ivnish Poland

    I can reproduce this:

    I opened Firefox private tab, voted, close tab, open new private tab and got error when voted again

  • ivnish Poland

    If I clear Drupal cache, I need to remove my previous anonymous vote from DB to reproduce this again

  • ivnish Poland

    The patch from MR doesn't help me

  • 🇮🇳India nitesh624 Ranchi, India

    Yes for me also patch doesn't seems to be solving the issue

  • 🇮🇳India nitesh624 Ranchi, India

    In the PollViewForm.php I have added
    \Drupal::service('page_cache_kill_switch')->trigger(); on Line 86 under else section.
    After that it seems to be working fine.

    As I saw in function showPollResults() already we have \Drupal::service('page_cache_kill_switch')->trigger(); line at top.
    So probably this issue could be due to this page_cache.

  • ivnish Poland

    I created a patch with #18 fixes. Please review and test

  • 🇨🇭Switzerland Berdir Switzerland

    If you get this error, then that means that you are not allowed to vote because that IP already voted. The "only" problem here is that there is a strange error instead of getting that feedback.

    The reason for that is that on the POST request, the form is built differently as a result of no longer having access, doesn't have a submit vote anymore and the core form/ajax system is confused about that.

    Just completely disabling page cache is _not_ the answer, that will obviously disable page cache on on any page with a poll, if you have that on the frontpage, or on article sidebars or something, that's going to hurt you.

    One solution I see here is to catch and handle that error in a nicer way, possibly either through a request subscriber (detect the problem before it happens, return info that voting isn't allowed anymore for this IP), or a response subscriber (detect the exception, do the same).

    Or maybe do some trickery that still adds the vote button on such cases on ajax post requests but it's submit action will then not actually do anything but display a message.

    Or change core to not explode like this on ajax requests, but not sure what to do instead then there.

  • 🇮🇳India nitesh624 Ranchi, India

    Thank @berdir to pitching in.
    Is there any way we can disable the cache on form. I tried setting max-age=0 on form build array. but still the problem persists.

    One solution I see here is to catch and handle that error in a nicer way, possibly either through a request subscriber (detect the problem before it happens, return info that voting isn't allowed anymore for this IP), or a response subscriber (detect the exception, do the same).

    For this approach where we can use request subscriber.? I am not able to understand approach.

  • 🇮🇳India nitesh624 Ranchi, India

    I am able to show the warning message to user using response subscriber.

    But still I am not able to understand why this is not happening on my local instance. Its happening only for hosted env. Is it because of IP restriction?

  • 🇮🇳India nitesh624 Ranchi, India

    I am checking the http response code, if the request is ajax request and the route is of poll entity then I am checking if already poll exits for that Ip address then replacing the form with status message on page.

  • 🇮🇳India nitesh624 Ranchi, India

    Now I am able to replicate this issue locally also with fresh vanilla drupal 10.1 installation.

  • 🇬🇧United Kingdom aps-Andrew

    Is there any movement on this? I saw it start to get updated and replicated at the end of last year and was hoping to run some stress tests against the polling, but was hoping this issue might be resolved before that time so that the stress test isn't potentially experiencing the same issue.

Production build 0.69.0 2024