Preventing Operation Aborted Scenarios
This post follows up on my original Operation Aborted post to provide some additional information and assistance for web site owners or 3rd party script libraries.
Recap
Nearly a year-and-a-half ago, I blogged about an error that can occur on some websites that generate content via script. This content can cause Internet Explorer’s HTML parser to get into an unrecoverable state, which makes it doubly-hard to find and diagnose why this error is happening. When this state occurs, the HTML parser cannot continue, and simply throws up its hands and admits: “Operation aborted!”
Early in IE8’s development, we put in a mitigation that alleviated the worst side-effects of this problem. Rather than show a modal dialog and then navigate away from the page after you press OK, instead we removed the dialog and transferred the error notification into the status bar (to the script error notification area). As a result, you are not interrupted by a dialog and you can continue to view the current web page. You may not have even noticed that this error occurred; yet the HTML parser does come to a grinding halt (for that tab only) and any additional content will never be processed.
Not too long after IE8 was released, we began hearing reports of IE8 customers continuing to see the old operation aborted dialog! While we knew that we hadn’t fixed every possible scenario that could cause the dialog to appear (it’s triggered as a catch-all for many subsystems such as the navigation stack and networking), we believed that we had mitigated the worst-cases. With recent reports of users seeing the Operation Aborted dialog in IE8 we investigated further to find any additional scenarios that could be triggering the dialog to appear (rather than the script error mitigation).
In the following two scenarios, the root cause of the Operation Aborted issue is the same (for details, please read my previous post), but the way in which it happens in these scenarios causes IE to bypass the mitigation that we put in place for IE8.
Scenario 1: Nested Parsing after Operation Aborted
<html>
<body>
<div>
<script type="text/javascript">
document.body.appendChild(document.createElement('div'));
document.write("Testing");
</script>
</div>
</body>
</html>
In the HTML above, the effect of the first line of the script is to trigger the Operation Aborted problem. In IE8 this is mitigated as previously mentioned. However, if sometime later a document.write API call is issued as shown in the second line of script, all versions of Internet Explorer, including 8, will present you with the old operation aborted dialog.
Scenario 2: Operation Aborted in error handlers
<html>
<body>
<script type="text/javascript">
window.onerror = function() {
var el = document.getElementById("div2");
el.appendChild(document.createElement("div"));
}
</script>
<div id="div1"></div>
<div id="div2" onclick="alert('hi';"></div>
</body>
</html>
In this HTML file, a script error (in the onclick event handler) has a run-time error, which causes the window object's onerror handler to be invoked. In this scenario, if Operation Aborted is triggered in the error handler, the dialog will also show in IE8.
Programmatically Detecting Operation Aborted
When this error dialog occurs, it is very hard for web developers to find the problem and fix it. Often (and in most cases we’ve seen) the problem is introduced in third-party scripts that are referenced by the affected page. To help web developers quickly find and fix the problem, we’ve written a little script that should help.
This script must be run as the first script in the page that is experiencing the Operation Aborted error. It overrides the usage of innerHTML and appendChild by first checking the parsing frontier before allowing the action. AppendChild is by far the most common DOM entry point that can trigger Operation Aborted, followed by innerHTML. The script may flag false positives, but we wanted to err on the side of being overly cautious.
This script relies on a feature enabled in IE8 standards mode only—Mutable DOM Prototypes. Thus, it will only work for pages that use IE's most standards-compliant mode. See this post on compatibility view for more details on the mode that IE is interpreting your page in. However, the operation aborted problems that this script identifies (in IE8 standards mode) also apply to IE7 and IE6 thereby helping you diagnose and fix this issue in any version of IE.
To use the following script follow these steps:
- Add a script element to the head of the page in question. This script element should be before any other script element on the page.
- Place the following script text within that script element (or reference a file containing it from the src attribute)
- Set the "f1" and "f2" feature values
- Setting "f1" to true will skip DOM calls that could potentially cause the Operation Aborted error. However, this will also result in a change in program flow, and other script errors could result.
- Setting "f2" to true stops program flow at the point of a potential Operation Aborted error and breaks into the debugger (external or built-in JavaScript debugger). This is where you can analyze each occurrence to see what assumptions were being made and how the program flow can be altered to prevent the problem.
- In IE, navigate to the page in question.
- Start the JavaScript debugger by pressing "F12" and then selecting the "Script" tab in the Developer Tools, and press the button "Start Debugging".
(function() {
// Feature switches
// WARNING: 'true' may cause alternate program flow.
var f1 = PREVENT_POTENTIAL_OCCURANCES = false;
var f2 = BREAK_INTO_DEBUGGER_AT_POTENTIAL_OCCURANCES = true;
if (!window.console) {
window.console = {};
window.console.warn = function() { };
}
var frontierCheck = function(host) {
// Is host on the frontier?
while (host && (host != document.documentElement)) {
if (host.parentNode && (host.parentNode.lastChild != host))
// This is not on the frontier
return true;
host = host.parentNode;
}
if (!host || (host != document.documentElement))
return true; // This node is not on the primary tree
// This check is overly cautious, as appends to
// the parent of the running script element are
// OK, but the asynchronous case means that the
// append could be happening anywhere and intrinsice
// knowledge of the hosting application is required
console.warn("Potential case of operation aborted");
if (f2)
debugger;
// Step up two levels in the call stack
// to see the problem source!!
if (f1)
return false;
else
return true;
}
var nativeAC = Element.prototype.appendChild;
Element.prototype.appendChild = function() {
// call looks like this:
// object.appendChild(object)
// Go back one more level in the call stack!!
if (frontierCheck(this))
return nativeAC.apply(this, arguments);
}
var nativeIH = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML").set;
Object.defineProperty(Element.prototype, "innerHTML", { set: function() {
if (frontierCheck(this))
nativeIH.apply(this, arguments);
}
});
})();
We recognize that the operation aborted dialog and its mitigated cousin in IE8 are still the source of significant web developer pain. We hope this information and prevention script help you to diagnose and fix issues related to Operation Aborted in IE8 (and older versions of IE).
-Travis Leithead
Program Manager
Comments
Anonymous
January 01, 2003
The comment has been removedAnonymous
January 01, 2003
@EricLaw I already was there and couldn't find any significant information on IE on WM6.5 or Zune on the windows mobile blog. I thought it was the IE team that build those browsers for the mobile platforms and we should be here for info on things like browsersidentifation strings and such...Anonymous
January 01, 2003
The comment has been removedAnonymous
September 03, 2009
The comment has been removedAnonymous
September 04, 2009
The comment has been removedAnonymous
September 04, 2009
How's IE 9 coming along? Will you still be using Trident or are you designing a new more robust layout engine? Trident really seams to be dated and inadequate for modern web sites. Is the strategy to avoid building a robust layout engine by pushing Silverlight?Anonymous
September 04, 2009
The comment has been removedAnonymous
September 04, 2009
@Hank: <q>Starting from scratch and making up new codenames is not how real engineers work. Real engineers refactor and improve their code."</q> That really seems to be working well for MS. http://a.deveria.com/caniuse/ With that strategy, the richest software company in the world can't compete with a non-profit organization. http://www.mozilla.org/foundation/. <q>As for the idea that layout engine "robustness" is somehow related to silverlight-- you clearly don't understand that business model at all.</q>. Ok wise guy, what is the business model?Anonymous
September 04, 2009
The comment has been removedAnonymous
September 04, 2009
The comment has been removedAnonymous
September 04, 2009
Could the team give a few posts on the mobile IE browser for Zune and Windows Mobile 6.5 ?Anonymous
September 04, 2009
@hAl: For content about the browsers on mobile platforms, you'll want to check out (or request at) those team's blogs. blogs.msdn.com/windowsmobile/ would probably be a good place to start.Anonymous
September 04, 2009
The comment has been removedAnonymous
September 04, 2009
@tester Yes this is "normal" (not ideal, but expected). I believe this happens because refresh does not reload the page from scratch, it just tries to re-parse the existing cached page... since the parser is busted for this page, then the browser just spins... The whole experience is just sub-optimal, and we're working on it.Anonymous
September 04, 2009
The comment has been removedAnonymous
September 04, 2009
@Hank: IE is losing market share and that is a reality. It has been for years now... http://www.computerworld.com/s/article/9137358/IE_tumbles_Firefox_regains_market_share_mojo Read the article, it's reality. Since you didn't read the Wikipedia article, here's the part that uses the word "rewrite" because you could not seem to be able to read between the lines in the paragraphs before it. So here it is, from the Wikipedia article:
In October 1998, Netscape announced that its next browser would use Gecko (which was still called NGLayout at the time) rather than the old layout engine, requiring large parts of the application to be rewritten. While this decision was popular with web standards advocates, it was largely unpopular with Netscape developers, who were unhappy with the six months given for the rewrite.
Rewrite - that is the word that you are looking for right? HTML, ECMAScript, CSS are superior technologies and are inherently more broadly deployed so I'm not sure what your point is.
Anonymous
September 04, 2009
The comment has been removedAnonymous
September 04, 2009
@EricLaw I already was there and couldn't find any significant information on IE on WM6.5 or Zune on the windows mobile blog. I thought it was the IE team that build those browsers for the mobile platforms and we should be here for info on things like browsersidentifation strings and such...Anonymous
September 04, 2009
Oh I know the answer: switch to chrome!Anonymous
September 05, 2009
@hAl: Nope, the team behind blogs.msdn.com/IE is responsible for the desktop browser only.Anonymous
September 05, 2009
@EricLaw: as far as I know, Windows Mobile 6.5 makes use of IE6's version of the Trident engine. Who is in charge of maintaining that code branch? Or is the Mobile team using a snapshot and never sync'ing up with upstream? If that is the case, then I guess all those 'highly critical' bugs discovered in IE 6 since the branching will remain present, and thus IE 6 Mobile should be avoided like the plague...Anonymous
September 06, 2009
@EricLaw - the Windows Mobile blog doesn't support commenting and of all the posts only 2 are tagged IE (one to do with widgets, the other with emulators) so the discussion points about Mobile IE are moot. Even if it is maintained by other development teams since this is the IE blog, this blog should at least state or link to info about the exact version of IE on Windows Mobile, what it supports, what it doesn't support and give some indication of whether it will ever be upgraded to a modern browser engine. hint hint, WebKit or Gecko. Even RIM's BlackBerry browser (which is already way better than Trident) is potentially getting upgraded to WebKit with RIM's latest acquisition. Currently due to lousy web standards support we don't support Mobile IE for our applications. Only BlackBerrys, iPhones, Pre, & Android.Anonymous
September 06, 2009
Then I would like to ask you on a better source than the windows mobile blog for info on the windows mobile browser ? Surely the IE and mobile browser teams have things in common ? Could you invite one of the windows mobile team expert for some guest post mayby ? The releases of the Zune and Windows Mobile 6.5 being so near with a new browser a lot of webdevelopers visiting this blog could do with some extra info on that browser as well.Anonymous
September 06, 2009
This is a problem I often have. The only solution I could think of was to switch browsers.Anonymous
September 07, 2009
Hi folks, here is an interesting one: http://brian.mastenbrook.net/display/36 Look towards the bottom!Anonymous
September 08, 2009
@Mitch: As I said, the team that maintains this blog is responsible for the desktop version of IE. I'm happy to pass along the request to the mobile team that they blog more about their browser.Anonymous
September 08, 2009
I think webdevelopers and other readers of this blog would appreciate that request.Anonymous
September 08, 2009
@EricLaw: do you mean that the Trident code is co-maintained by both the desktop and mobile teams? If this is the case, and the mobile team don't 'broadcast' when they do their code pull, then indeed you can't know which code revision they are currently using. Sorry 'bout the noise.Anonymous
September 09, 2009
@Mitch: I have no idea what would lead you to that conclusion. MobileIE & DesktopIE are far from the only cases where multiple teams work in a single source base. A few years ago, Larry wrote up a short post on the topic (http://blogs.msdn.com/larryosterman/archive/2005/02/01/364840.aspx). I'm sure that over the last two decades or so other folks have written on the subject as well.Anonymous
September 09, 2009
The comment has been removedAnonymous
September 09, 2009
Gerard, that's a genius question! Why does Microsoft software have bugs? They should just fix all the bugs, then ship the programs. I can't believe no one thought of that before! You're brilliant! They should hire you!Anonymous
September 09, 2009
The comment has been removedAnonymous
September 09, 2009
Gerard, Thank you! Now I understand that all other browser have no bugs!! I will avoid Microsoft software from now on. Thank you for helping me! Boo Microsoft. Yay genius Gerard!Anonymous
September 10, 2009
@Bob - sarcasm aside Gérard has many good points and has been one of the most vocal members of this community working on fixing IE bugs. I welcome every comment Gérard makes as he often goes into great detail about exactly what the issues are and where they first appeared with links to test cases etc. As he indicated the lack of good DOM method support is the main reason why IE fails to meet the grade for developers. The Specification API states that method "X" will do "this", yet in IE it is hard to find ANY DOM method that doesn't have a flaw in the implementation. I too have filed many bugs, ranted at the lack of standards support, lack of public bug tracking for years. My hope when IE7 was in development was that MS had seen the light and was going to do "the right thing" and open up public bug tracking. However that faded when not only did it not happen, but the bug tracking they had was taken offline. When IE8 was in beta I hoped again that the bug tracking would be public, and fixed but no luck. I sincerely hope there is a plan to do the right thing with the bug tracking for IE9... we've waited long enough.Anonymous
September 10, 2009
The comment has been removedAnonymous
September 11, 2009
yeah..."mitigation" in IE context means "Premature Hacked Patch"Anonymous
September 12, 2009
The comment has been removedAnonymous
September 13, 2009
The comment has been removed