How do you handle runtime exceptions caused by extensions?

What is your practice of handling runtime exceptions in Elm caused by DOM manipulations caused by browser extensions/plugins?

We recently ran into this because of the Grammarly Chrome extension.

Haven’t looked up recently but Runtime errors caused by Chrome extensions is a related issue.

1 Like

It definitely is. I’m now fishing for good practices around this.

+1 to this, @Birowsky. I don’t have an answer, but I ran into the same thing during a demo using an app I had written in Elm. While I didn’t figure out the problem, I observed that the Elm runtime seemed to recover without reloading the page when I disabled the plugin during the demo. Maybe it’s possible to at least detect the plugin and display a warning message?

I read through the Chrome Plugins link above and realize now there’s a viable workaround I wish I had known about before. Oh well, please disregard my previous message.

How do you handle runtime exceptions caused by extensions?

Case by case. There is no systemic approach because the very concept of virtual DOM is flawed. It can’t get over the unfortunate fact it’s not the only one to modify the DOM.

Another viewpoint is that the very concept of browser plugins is flawed. Browsers should show websites as they are meant to be shown and not modify them in any way.

So don’t try to handle the runtime exceptions caused by extensions in any way - just inform users that they should not use browser plugins.

That’s true. But that’s like complaining about weather. Extensions are not going away any time soon, neither do people writing crappy code. You file a bug report and they like - I don’t care, dude :fu:
And you’re like - Okay :frowning:
And people using your app only see your app being broken, they don’t care whose fault it really is either.
This is one of those cases you lose despite of being right all the time.

Hold up. What is this viable workaround you speak of?

Or are you referring to jinjor’s patch?

1 Like

At work we render all our textareas using two helpers functions, so we added Html.Attributes.attribute "data-gramm_editor" "false" to both of them. That got rid of the majority of all virtual dom errors in our error tracking service.

2 Likes

@jinjor’s workaround: data-gramm_editor=“false”.

2 Likes

At my last job we had trouble with some browser extensions trying to add their own html elements to the top of the <body></body> tag’s children. Which would lead to the Elm virtual dom finding a different element than it expects at certain positions in the dom.

The solution we came to, that we learned from another Elm company, was to modify the compiled javascript from the Elm compiler, so that Browser.application doesnt look for the <body> tag, but instead looks for a <div> directly under the body. Then, our html file that we served would have that <div> in that position too.

Maybe not VDOM precisely, but Elm’s particular VDOM implementation.
There are some other implementations out there that do not keep an internal model of the DOM as a base for the next update, but they use the real DOM state (which could have been altered by an external script) as the input to figure out the next changes.
I remember someone proposed change in the VDOM algorithm to Evan at elm-europe, but don’t know how it landed.

Would it be a nice feature on a future version of the Elm compiler to be able to pass this as a parameter to the compiler? So you don’t have to do a post-compilation edit on the generated .js.

This is a problem for React as well: https://bugs.chromium.org/p/chromium/issues/detail?id=872770

You shouldn’t need to edit the compiled .js. You can pass a node parameter when you initialize the elm application, and it will place the app’s html there rather than directly in the body.

With Browser.element you are correct, but if you are using a Browser.application Elm will take over the <body> node.

Perhaps that would be a better way to do it, rather than a compilation time flag - make Browser.application also allow the node to take over to be specified.

1 Like

Im not sure. If there was an option to solve the problem, then I guess thats nice because it solves the problem. But its also a kind of obscure configuration detail. 1 configuration detail per problem that could possibly be solved by a configuration detail seems like a bad direction to go in tho, because such problem are possibly endless.

One solution could be telling the Elm.init() function in JS what element to fill up. So you can pass in documet.body or anything else you want. Its worth noting that this is similar to how things were in 0.18, which didnt have the problem I originally mentioned. 0.19 changed, in that it doesnt allow Elm apps that do navigation to render in anything less than the <body/>, and I believe that choice was because that would permit the possibility of a small Elm widget being an Browser.application and therefore having full control over the navigation. It doesnt seem like a small widget should have that responsibility. Its likely to get into navigation conflicts with other things on the page.

Just reverting that decision in 0.19 could be the simplest solution, but it would become a possible again for small Elm widgets to control navigation. And anyway, I kind of like Elm’s ambitious approach of taking over everything. Seems like the right direction, even if its difficult and uncharted territory for frontend technology.

So again, I dont know how to solve it.

I think this is a higher kinded problem of the DOM API … I think one solution could be DOM manipulation transactions and DOM manipulation locks. I think this needs to be addressed at the DOM specification level.

1 Like