Page MenuHomePhabricator

Uncaught TypeError: $.cookie is not a function at Object.setupEditLinks
Closed, InvalidPublic

Description

Error trending https://logstash.wikimedia.org/app/dashboards#/doc/logstash-*/logstash-2021.03.03?id=Iw7f-HcBWKe2MTdRAflz (third most frequent)

TypeError: $.cookie is not a function
    at Object.get (<anonymous>:273:241)
    at getLastEditor (<anonymous>:181:246)
    at getEditPageEditor (<anonymous>:181:744)
    at isOnlyTabVE (<anonymous>:183:272)
    at Object.setupEditLinks (<anonymous>:184:87)
    at HTMLDocument.<anonymous> (<anonymous>:197:907)
    at mightThrow (URL1:49:149)
    at process (URL1:49:808)

URL1: https://en.wikipedia.org/w/load.php?lang=en&modules=jquery&skin=vector&version=tqh7e

Event Timeline

VisualEditor doesn't use $.cookie directly, we use mw.cookie.get. This error would mean that 'mediawiki.cookie' is loaded, but its dependency 'jquery.cookie' is not. I have no explanation for how that would happen, but it sounds like potentially a much bigger problem if RL depedencies stopped working.

Our tests are passing and the dependency system is generally working fine. Let's assume this is a JavaScript issue and not a ResourceLoader issue.

Some questions to help you on your way:

  • What's the rate?
  • Any particular browsers or wikis affected only?
  • Does it only happen via the VisualEditor entry point? If not, are there a handful of major entry points, or literally any random code using cookies? What do they have in common?
  • Based on looking at the source code, do we have a theory for how it would happen?
  • Can it be reproduced by us?
  • Do we have contact with someone else that can?

If not wide spread, then I would assume this is just noise from a crappy browser or user script unloading or replacing global variables.

The VisualEditor error is defnitely not "third most frequent", unless the situation with errors has drastically improved since I last looked, because there is a total of 29 hits logged in the last 30 days: "TypeError: $.cookie is not a function" AND setupEditLinks

The $.cookie errors in general are more common (but they are mostly not caused by VisualEditor), 8,619 hits: "TypeError: $.cookie is not a function"


The most common backtrace I've seen looked like this: https://logstash.wikimedia.org/app/discover#/doc/logstash-*/logstash-2021.03.04?id=r6gA_ncBA6MeBtBqqp45

at Object.get  ...load.php...:412:241
at run  ...load.php...:87:569
at setActive  ...load.php...:88:10
at HTMLDocument.onVisibilitychange  ...load.php...:88:348

…which is from code in WikimediaEvents extension: https://github.com/wikimedia/mediawiki-extensions-WikimediaEvents/blob/650ceb8d3be11030571485ac31ee26ff12a158a5/modules/ext.wikimediaEvents/sessionTick.js#L83

But this failure is just as nonsensical as the one in VisualEditor – mw.cookie.get is called without an error (it appears in the stacktrace as Object.get), then $.cookie is called but it doesn't exist, even though it must have been loaded as a dependency.

(Aside: Looks like that code was missing the dependency on mw.cookie until recently – 070385599712fa24f5ecf0dd3bc7580bd106d39d – but if this was causing this problem, the error message would be about mw.cookie being undefined, not $.cookie.)

Feel free to re-open if you research this better.

The VisualEditor error is defnitely not "third most frequent", unless the situation with errors has drastically improved since I last looked, because there is a total of 29 hits logged in the last 30 days: "TypeError: $.cookie is not a function" AND setupEditLinks

I was looking ast last 12hrs. Last 30 days is not really a good indicator, since many of the bugs were fixed in previous deploys.

The $.cookie errors in general are more common (but they are mostly not caused by VisualEditor), 8,619 hits: [[ https://logstash.wikimedia.org/goto/09f151d6c570a1864667db953130e5e6 | "TypeError: $.cookie is not a function" ]


The most common backtrace I've seen looked like this: https://logstash.wikimedia.org/app/discover#/doc/logstash-*/logstash-2021.03.04?id=r6gA_ncBA6MeBtBqqp45

at Object.get  ...load.php...:412:241
at run  ...load.php...:87:569
at setActive  ...load.php...:88:10
at HTMLDocument.onVisibilitychange  ...load.php...:88:348

…which is from code in WikimediaEvents extension: https://github.com/wikimedia/mediawiki-extensions-WikimediaEvents/blob/650ceb8d3be11030571485ac31ee26ff12a158a5/modules/ext.wikimediaEvents/sessionTick.js#L83

This is captured in T275948.

But this failure is just as nonsensical as the one in VisualEditor – mw.cookie.get is called without an error (it appears in the stacktrace as Object.get), then $.cookie is called but it doesn't exist, even though it must have been loaded as a dependency.

It previously wasn't being loaded as a dependency. See T275948.

(Aside: Looks like that code was missing the dependency on mw.cookie until recently – 070385599712fa24f5ecf0dd3bc7580bd106d39d – but if this was causing this problem, the error message would be about mw.cookie being undefined, not $.cookie.)

Sure.

Feel free to re-open if you research this better.

My current hunch is that scripts/extension might be disabling the jquery cookie plugin, but I'll keep an eye on it. If we can't debug this one any further, that's fine.

I will note there seem to be a lot of issues relating to jquery plugins not being defined that can't easily be explained.
These errors include TypeError: $(...).updateTooltipAccessKeys is not a function , TypeError: $tabContainer.on(...).on(...).collapsibleTabs is not a function, Uncaught TypeError: $.Deferred is not a function as well as this one. In some cases $ is undefined.

@Krinkle is there any way ResourceLoader could interfere with jQuery plugin registration, aside from the obvious case where someone replaces the existing version of jquery?

@Jdlrobson That's a lot of issues combined. In general we've seen this when scripts either override $ itself (often accidentally not realising they are using globals), or with property iterators on objects that accidentally override/modify properties.

In general these problems are hard to trace, because a script that was run for that particular user at an earlier phase is the actual problem and you are just seeing the destructive effects of the problem.

@Krinkle is there any way ResourceLoader could interfere with jQuery plugin registration, aside from the obvious case where someone replaces the existing version of jquery?

ResourceLoader? No. JavaScript? Yes. Running delete $.cookie; from any kind of script will throw it away. Similarly, something like $ = document.querySelectorAll; or window.$ = /And Now for Something Completely Different/; will also result in jQuery and any plugins being dereferenced from the global scope.

However, we've seen this kind of issue back in 2009 and 2010 and ResourceLoader has built-in protection for the common case here. It retains a reference to the original object behind the most-used globals (mw and $) and binds them lexically to individual modules so that one could actually do delete window.$ and most things will still work and have their own reference unaffected. This protects against the common case of the global being overwritten. However, code explicitly doing someting like $.fn = {}; or delete $.cookie; will still have the expected destructive effect.