Open Bug 2041680 Opened 16 days ago Updated 5 days ago

"Script '<file>' result is non-structured-clonable data" error from scripting.executeScript

Categories

(WebExtensions :: General, defect, P3)

defect

Tracking

(Not tracked)

People

(Reporter: robwu, Unassigned)

References

(Blocks 1 open bug)

Details

The tabs.executeScript and scripting.executeScript (and userScripts.execute) methods return their result to the caller. When an error happens, there are two bugs though:

  • if any of the script results are not structurably cloneable, the whole executeScript call rejects. In the scripting.executeScript API, the expectation is for errors to be captured in the individual results, and not for them to fail the whole call.
  • the reported filename can be inaccurate. The assumption is that the serialization error came from the last executed script. This is usually accurate, except when multiple scripts are run and the error was thrown from one of the earlier scripts (e.g. throw document;).
    • This only affects scripting.executeScript and userScripts.execute (being developed in bug 1930776), not tabs.executeScript (the latter executes only one script).
    • Fixing this requires keeping track of the script that is currently being executed. I'm not sure if it is worth the effort, but documenting it here just in case.

Relevant history:

In bug 1339559, the last file name is reported when the result cannot be cloned: https://searchfox.org/firefox-main/rev/d4b3c257364526e1129a38d87d6c35e672dc10a5/toolkit/components/extensions/ExtensionContent.jsm#1136-1150
The fix tries to serialize the result of executeScript with cloneInto before returning the message via IPC, and reports the last file name otherwise. The "last file name" logic is fine here because tabs.executeScript supports only one file or code.

In bug 1317697, the implementation was refactored and now aggregates all results from the executions in the same process before cloning. This means that if any one script returns a clone error, all results are dropped.

Today, that logic is still largely the same: https://searchfox.org/firefox-main/rev/1f7030c8de8f2b349c7d91d7b5a3253c109a1cc1/toolkit/components/extensions/ExtensionContent.sys.mjs#1499-1525

One aspect of the current approach is that we will fail fast(er) if there is a cloning error.

With executeScript, the same script is run repeatedly, and it is likely that a cloning error in any of them also happens consistently with the others.
One could argue that in this case it is preferable to reject the whole call instead of returning individual cloning errors, for the following reasons:

  • scripting.executeScript (and userScripts.execute) aggregate errors across multiple executions. If an extension was careless enough to return a non-cloneable result, odds are that they don't check the returned errors either. Rejecting the whole scripting.executeScript can result in a more visible error encouraging devs to fix the issue.
  • If the return value is consistent, there is no point in trying to clone all individual results - it would be a wasted effort.

Whether the above "benefits" outweigh the deviation from the shape of the scripting.executeScript definition is not clear.

Severity: -- → S4
Priority: -- → P3
See Also: → 1824896
You need to log in before you can comment on or make changes to this bug.