Hacker News new | ask | show | jobs
by helsinkiandrew 1860 days ago
Hang on: The Tee Spring code checks if GA is there and works without it, the website breaks because Ad block replaces GA with a fake object that doesn't have the same API.

Perhaps some companies have the resources to check if their websites run with different ad blockers, but expecting websites to work when plugins are replacing and breaking running code is a big ask.

8 comments

I think the point is that Google Analytics shouldn't be an essential part of your site, so it totally breaking for any reason should be unnoticeable to the end user.
If it had broken, the code in the post would have worked. How exactly is code supposed to handle a dependency existing, but not being the API shape that it should be because a browser extension added an incomplete stub? Should every line of code get wrapped in try/catch?

There's a big difference between "resilient against a missing dependency" and "being resilient in the face of getting literally any object instead of the dependency you expected to get."

> Should every line of code get wrapped in try/catch?

Everything Google Analytics does is expendable, so the block of code that deals with it should be wrapped in try/catch.

> There's a big difference between "resilient against a missing dependency" and "being resilient in the face of getting literally any object instead of the dependency you expected to get."

If Google pushes a breaking change to the Google Analytics API tomorrow, that shouldn't break checkout either.

> Should every line of code get wrapped in try/catch?

For third party dependencies that might not get loaded for whatever reason? Yes, sure. There are better ways to do it, but that's the idea.

The code listed does check if it's been loaded. The stub that gets loaded is wrong. How do you guard against that?
It's not. It can work without it. The issue is something is pretending to be Google Analytics just enough to cause problems.
Yeah this is very clearly on the ad-blocker.

I think TeeSpring has the right idea - they're checking that GA is loaded, if it is, then do stuff with it, if it's not, then don't.

I don't understand how a website can and should be expected to adapt to a browser plugin changing the APIs they depend on out from underneath them.

> I think TeeSpring has the right idea - they're checking that GA is loaded, if it is, then do stuff with it, if it's not, then don't.

I think they could go one step further and may be try...catch (sandbox) all access to third-party services that aren't critical.

User-agents, which browsers are, expectedly do put a lot of control in the hands of the end-users. Such breakages should be factored in and worked around (provided there are enough engineering resources to throw at the problem, of course).

Exactly. A browser's job as the user's agent is to do what the user wants it to do. It's not an ABI. If an end-user's browser is configured to do something you, as a developer, don't want or expect, and that breakage causes the loss of a sale, it's kind of on you: Either take a principled stand about "what browsers should be doing" and accept the lost sale, or try/catch around non-critical code to make your site more robust to the user's configuration choices.
The ad blocker is probably trying to do the right thing for their users, to. Too many websites check that GA is loaded, if it is, then do stuff with it, if it's not, then redirect to a "Please disable your ad-blocker" page.
I think the key point is that the only way to do this right is to have a quirks list and both implementations, and pick the implementation based on that list.
Why does checkout depend on Google APIs?
But you don't even need to check, you just don't blow up and still check out if it doesn't work?

Put it this way, forget adblock, if the GA call fails, it should still check out. (Assuming the problem doesn't affect other stuff too, like internet down or whatever.)

I think the problem is that with the code-as-written, if the GA call fails, the relevant `window` field won't be populated, which the code is detecting.

Given the hyper-malleable nature of JavaScript in an HTML page in a user-agent owned by the end user, at some point the developer has to draw a line in the sand and say "This category of failure modes is not checked," because it's mathematically impossible to check all possible failure modes in that configuration. "An extension is intentionally faking an object in the `window` context" just happens to be on the other side of the "don't check" line for this application, because it's extremely unlikely (and, one could argue, user-self-inflicted).

> Perhaps some companies have the resources to check if their websites run with different ad blockers,

Checking the top 3 adblockers that command the majority of market share would be a much smaller ask - maybe smaller than a check-mobile-browser sized ask.

I believe that Firefox is replacing some Facebook JavaScript with a stub, to avoid that sites break because some tracking bits are missing.

So the reason why the GA object is replaced, rather than removed, is because removing it would break other sites. Tee Spring is trying to do the right thing, but fail because other sites don’t do the same.

Both uBlock Origin and TeeSpring are trying to do the right thing, but in incompatible ways. I would say in this case the onus is on uBlock Origin to provide a stub that is as transparent as possible.
Don't put GA there, then.
Chrome store says 10 million+ users (I expect it's vastly higher than that) 24,000 reviews. Firefox says 5 million users and 12,000 reviews.

Ignore it at your peril. If you want to make sales, you need to test the ways your prospective customers want to buy.

Just stop using Google spyware. Takes zero amount of resources.