Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

QCoreApplication::postEvent: Unexpected null receiver #39

Closed
alexslade opened this issue Apr 27, 2011 · 22 comments
Closed

QCoreApplication::postEvent: Unexpected null receiver #39

alexslade opened this issue Apr 27, 2011 · 22 comments

Comments

@alexslade
Copy link

Getting this message popping up in 2 different cucumber test suits, not sure where it's coming from. Any ideas?

@jferris
Copy link
Contributor

jferris commented Apr 27, 2011

These are hard to track down. They happen when we try to send an event to an object we already deleted. In capybara-webkit, this is usually when a Command subclass receives an event after it's deleted. The best way I know of to track them down is to use print debugging to figure out what the socket dialog looks like that causes the error.

@fd
Copy link

fd commented Apr 27, 2011

Putting an if (m_command != NULL) around this line fixed the problem for me

@jferris
Copy link
Contributor

jferris commented Apr 27, 2011

Is there a good way to reproduce this? Can you write a test?

@fd
Copy link

fd commented Apr 27, 2011

Well a couple of days ago I first noticed the bug. So I did some digging and I didn't find out why m_command is NULL. But google pointed me in the direction of the NULL vs. deleteLater thing. Qt also has a ENV flag which shows some more debugging output: QT_FATAL_WARNINGS=1

@jferris
Copy link
Contributor

jferris commented Apr 27, 2011

Right; I need to know what actually causes this issue, though. Adding that if statement will only mask the symptom and not fix the problem, because it shouldn't be trying to delete a NULL command in the first place. I think the most likely culprit is that a command is emitting a response twice, which shouldn't happen.

@keithpitt
Copy link

This error pops up for me every once and a while. I'm trying to use #find_field at the time. I get this output in my cukes:

QCoreApplication::postEvent: Unexpected null receiver

And it fails with the following error:

Unknown command: f::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')][((./@id = 'Product Group' or ./@name = 'Product
 (Capybara::Driver::Webkit::WebkitError)
./features/step_definitions/input_steps.rb:3:in `/^the "([^"]*)" drop-down should contain the option "([^"]*)"$/'
features/product_groups.feature:19:in `Then the "Product Group" drop-down should contain the option "Shoes"'

My step that produces the error, looks like this:

Then /^the "([^"]*)" drop-down should contain the option "([^"]*)"$/ do |label, selected_options|
  field = find_field(label)
  options = all(%{##{field[:id]} option[selected]}).map { |a| a.text }
  options.join(', ').should == selected_options
end

It blows up on the field = find_field(label) line. I hope this helps...

@jferris
Copy link
Contributor

jferris commented May 5, 2011

I found a couple possible paths that led to this error and fixed them. Can you guys try again with 0.3.0?

@jferris
Copy link
Contributor

jferris commented Jun 14, 2011

I'm going to assume this is fixed unless somebody else runs into it.

@jferris jferris closed this as completed Jun 14, 2011
@cmeiklejohn
Copy link
Contributor

I was experiencing this but as of 0.4.1 I'm not anymore.

@alexslade
Copy link
Author

Still getting the error with 0.5.0
What's worse, it seems to be a bit sporadic, one example scenario will pass 30% of the time.

cannot select option, no option with text 'Call To Action' in select box 'Select the type of component' (Capybara::ElementNotFound)

(A couple of steps after the 'QCoreApplication::postEvent: Unexpected null receiver' gets printed. If the postEvent error doesn't happen, the feature passes)

What debug info would be most useful here to work out what's going on?

@ignu
Copy link

ignu commented Jun 15, 2011

This is happening for me on the 1.0 branch when I try to run any javascript.

@cmeiklejohn
Copy link
Contributor

I'm still getting this. Just experienced it on 0.4.0.

@mikepack
Copy link

Still an issue for me. I noticed that when I do run into this problem, it happens on almost all tests in the suite. When it doesn't occur, it happens on none of them. It's also quite sporadic and unpredictable, occurring sometimes on a test that has previously passed and is unchanged.

Sometimes I receive this corresponding error:
INVALID_EXPRESSION_ERR: DOM XPath Exception 51: The expression had a syntax error or otherwise is not a legal expression according to the rules of the specific XPathEvaluator.

@keithpitt
Copy link

Just out of interest, can you run your HTML through some sort of validator?

@alto
Copy link

alto commented Sep 26, 2011

I get this unpredictable error message as well, using 0.5.0 .

@bwbuchanan
Copy link
Contributor

Firstly, many thanks to the authors and maintainers of this gem for saving me from Selenium hell and making it possible for me to do awesome things. <3

Secondly, please reopen this issue. This bug is still present, and it's evil. I just spent hours and hours tracking it down.

In rare instances, it looks like WebKit is dispatching the pageFinished() signal twice (maybe when a redirect happens, under some conditions?). Possibly a WebKit bug?

Anyway, webkit_server doesn't expect this to happen, so this is what's happening:

  1. Capybara sends a "Visit" command to webkit_server.
  2. Visit object is instantiated
  3. Visit object listens for pageFinished()
  4. Page loads. Webkit sends pageFinished() signal
  5. Visit::loadFinished() invoked by the signal
  6. Visit::loadFinished() emits finished(Response)
  7. Response is sent to Capybara
  8. Visit object is queued for destruction.
  9. Capybara begins sending the next command to webkit_server
  10. Connection reads the first few parts of the command string
  11. Webkit sends pageFinished() AGAIN for some reason.
  12. Visit::loadFinished() invoked by the signal
  13. Visit::loadFinished() emits finished(Response)
  14. Bogus duplicate response is sent to Capybara, confusing it mightily
  15. Visit is queued for destruction again. This is probably where the ::postEvent warning happens.
  16. Connection's command-reading state is reset at the end of Connection::writeResponse()
  17. Connection reads the remainder of the command, and also becomes very confused; it has just read a command argument into the m_commandName buffer.
  18. Connection sends error message to Capybara
  19. Capybara raises exception
  20. Developer tears hair out and loses much sleep

Suggested fixes:

  1. Add this line to Visit::loadFinished() to prevent this object from being used after it is queued for destruction:

    disconnect(page(), SIGNAL(pageFinished(bool)), this, SLOT(loadFinished(bool)));

  2. For robustness, and to make the code more understandable, move Connection's command-reading state reset code from writeResponse() to startCommand(). I understand that it might make debugging easier to have the currently-executing command name and arguments hanging around, but the async coding style just makes this into an obfuscation.

  3. To avoid future issues, modify webkit_server so that it is not possible for multiple commands to be executing simultaneously. The way webkit_server is processing commands asynchronously, the order of the responses is not guaranteed to match the order that the commands were received. Of course, the current Capybara-side driver as-written can't send a command while it is waiting for the response to a previous command, but who knows what modifications might be made down the road and lead to some poor future bleary-eyed developer desperately crawling through Google in search of this bug report.

  4. Refactor the ad-hoc state machines in the Connection class.

While I am 99% certain that my analysis is correct, this bug is so hard to reproduce that I can't actually test the fix. I will run this under load in production for a while and hopefully there are no recurrences!

@bwbuchanan
Copy link
Contributor

I've been running with this fix continuously for about 6 hours now. The "QCoreApplication::postEvent: Unexpected null receiver" error has not reared its ugly head, I and I have observed no regressions.

@keithpitt
Copy link

+1

1 similar comment
@fd
Copy link

fd commented Sep 29, 2011

+1

@jferris jferris reopened this Sep 29, 2011
@jferris
Copy link
Contributor

jferris commented Sep 29, 2011

QCoreApplication::postEvent is almost always raised when a single command emits finished twice. This isn't ever supposed to happen, but bugs like the one you found can cause it. I think this is happening in your case because two page loads somehow trigger after a visit, and we rely on command deletion to clean up signals. Your fix looks like the correct one, but I won't pull it without a test to prove it. We need tests for issues like these, even though they're difficult to write, because the issue will definitely reappear again after we refactor or add new commands.

Also, thanks for the suggestions as to how to improve capybara-wekbit. I'm working on some things that will make issues like this easier to debug.

I think it's worth explaining that capybara-wekbit doesn't execute multiple commands at once. It holds onto a command name and arguments because it doesn't necessarily get these all at once from the connection. Once we've gotten them all, we build a command and discard the command name.

If we receive a new command and the browser is busy loading a page for some reason (possibly because of setTimeout or another asynchronous load), we wait until the page is finished loading to run the new command. Because most pages are loaded asynchronously, this can lead to the appearance that more than one command is running at once. However, that's never the case.

@bwbuchanan
Copy link
Contributor

I don't think I can justify the additional investment into building some complicated test jig to reliably trigger a race condition, so someone else will have to take up the torch.

jferris pushed a commit that referenced this issue Oct 1, 2011
jferris added a commit that referenced this issue Oct 1, 2011
@jferris
Copy link
Contributor

jferris commented Oct 1, 2011

Thanks, @bwbuchanan. I released 0.7.1 with your fix.

If anybody runs into this again, please create a new issue and attach a debug log. Check out this page for information on generating a good debug log: https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes

@jferris jferris closed this as completed Oct 1, 2011
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants