Skip to content

Commit

Permalink
Don’t report IE error for freed script in event and timeout handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
querymetrics authored and nicjansma committed Apr 3, 2018
1 parent 031c1fb commit cd898d2
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 1 deletion.
10 changes: 9 additions & 1 deletion plugins/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,15 @@
return fn.apply(that, arguments);
}
catch (e) {
// error during callback
// Check for IE/Edge error "Can't execute code from freed script"
if (e.number === -2146823277 &&
(via === BOOMR.plugins.Errors.VIA_EVENTHANDLER || via === BOOMR.plugins.Errors.VIA_TIMEOUT)) {
// Event listeners that reference freed scripts don't generate errors in IE
// Our call to a freed script does though, don't report the error
return;
}

// Report error during callback
impl.send(e, via);

// re-throw
Expand Down
44 changes: 44 additions & 0 deletions tests/page-templates/14-errors/26-freed-events.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<%= header %>
<%= boomerangScriptMin %>
<script src="26-freed-events.js" type="text/javascript"></script>
<iframe id="testFrame"></iframe>
<script>
var testFrame = document.getElementById("testFrame");
var testFrameDoc = testFrame.contentWindow.document;
testFrameDoc.open();
testFrameDoc.write("\x3cscript\x3efuncInIframe \x3d function(event) { console.log(\x22hello from iframe\x22); }\x3c/script\x3e");
testFrameDoc.close();

BOOMR_test.init({
testAfterOnBeacon: 1,
Errors: {
enabled: true,
monitorEvents: true,
sendAfterOnload: true,

// turn off global so it doesn't get in the way
monitorGlobal: false,
monitorTimeout: false
}
});

if (window.addEventListener && window.postMessage) {
// by the time the message event callback is called the iframe would have been freed
// in IE/Edge this causes a `Can't execute code from freed script` error
// in Chrome, the callback will execute
window.addEventListener("message", testFrame.contentWindow.funcInIframe);

// changing the src causes the script to be freed in IE/Edge
testFrameDoc.open();
testFrameDoc.write("");
testFrameDoc.close();

setTimeout(function() {
window.postMessage("foo", "*");
}, 100);
}
</script>

<!-- delay the page by 1second so an error can fire -->
<img src="/delay?delay=1000&amp;file=/assets/img.jpg" style="width: 100px" />
<%= footer %>
24 changes: 24 additions & 0 deletions tests/page-templates/14-errors/26-freed-events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*eslint-env mocha*/
/*global BOOMR_test,assert*/

describe("e2e/14-errors/26-freed-events", function() {
var tf = BOOMR.plugins.TestFramework;
var t = BOOMR_test;

if (!window.addEventListener) {
it("Skipping on browser that doesn't support addEventListener", function() {
});

return;
}

it("Should have only sent a page-load beacon", function(done) {
this.timeout(10000);
t.ensureBeaconCount(done, 1);
});

it("Should have no error on the page-load beacon", function() {
var b = tf.lastBeacon();
assert.isUndefined(b.err);
});
});
38 changes: 38 additions & 0 deletions tests/page-templates/14-errors/27-freed-timeout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<%= header %>
<%= boomerangScriptMin %>
<script src="27-freed-timeout.js" type="text/javascript"></script>
<iframe id="testFrame"></iframe>
<script>
var testFrame = document.getElementById("testFrame");
var testFrameDoc = testFrame.contentWindow.document;
testFrameDoc.open();
testFrameDoc.write("\x3cscript\x3efuncInIframe \x3d function(event) { console.log(\x22hello from iframe\x22); }\x3c/script\x3e");
testFrameDoc.close();

BOOMR_test.init({
testAfterOnBeacon: 1,
Errors: {
enabled: true,
monitorTimeout: true,
sendAfterOnload: true,

// turn off global so it doesn't get in the way
monitorGlobal: false,
monitorEvents: false
}
});

// by the time the setTimout callback is called the iframe would have been freed
// in IE/Edge this causes a `Can't execute code from freed script` error
// in Chrome, the callback will execute
setTimeout(testFrame.contentWindow.funcInIframe, 100);

// changing the src causes the script to be freed in IE/Edge
testFrameDoc.open();
testFrameDoc.write("");
testFrameDoc.close();
</script>

<!-- delay the page by 1second so an error can fire -->
<img src="/delay?delay=1000&amp;file=/assets/img.jpg" style="width: 100px" />
<%= footer %>
17 changes: 17 additions & 0 deletions tests/page-templates/14-errors/27-freed-timeout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*eslint-env mocha*/
/*global BOOMR_test,assert*/

describe("e2e/14-errors/27-freed-timeout", function() {
var tf = BOOMR.plugins.TestFramework;
var t = BOOMR_test;

it("Should have only sent a page-load beacon", function(done) {
this.timeout(10000);
t.ensureBeaconCount(done, 1);
});

it("Should have no error on the page-load beacon", function() {
var b = tf.lastBeacon();
assert.isUndefined(b.err);
});
});

0 comments on commit cd898d2

Please sign in to comment.