123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- // Copyright 2009 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- goog.provide('goog.debug.ErrorReporterTest');
- goog.setTestOnly('goog.debug.ErrorReporterTest');
- goog.require('goog.debug.Error');
- goog.require('goog.debug.ErrorReporter');
- goog.require('goog.events');
- goog.require('goog.functions');
- goog.require('goog.testing.PropertyReplacer');
- goog.require('goog.testing.TestCase');
- goog.require('goog.testing.jsunit');
- goog.require('goog.userAgent');
- goog.require('goog.userAgent.product');
- MockXhrIo = function() {};
- MockXhrIo.prototype.onReadyStateChangeEntryPoint_ = function() {};
- MockXhrIo.protectEntryPoints = function() {};
- MockXhrIo.lastUrl = null;
- MockXhrIo.send = function(
- url, opt_callback, opt_method, opt_content, opt_headers, opt_timeInterval) {
- MockXhrIo.lastUrl = url;
- MockXhrIo.lastContent = opt_content;
- MockXhrIo.lastHeaders = opt_headers;
- };
- var errorReporter;
- var originalSetTimeout = window.setTimeout;
- var stubs = new goog.testing.PropertyReplacer();
- var url = 'http://www.your.tst/more/bogus.js';
- var encodedUrl = 'http%3A%2F%2Fwww.your.tst%2Fmore%2Fbogus.js';
- function setUp() {
- // TODO(b/25875505): Fix unreported assertions (go/failonunreportedasserts).
- goog.testing.TestCase.getActiveTestCase().failOnUnreportedAsserts = false;
- stubs.set(goog.net, 'XhrIo', MockXhrIo);
- goog.debug.ErrorReporter.ALLOW_AUTO_PROTECT = true;
- }
- function tearDown() {
- goog.dispose(errorReporter);
- stubs.reset();
- MockXhrIo.lastUrl = null;
- }
- function throwAnErrorWith(script, line, message, opt_stack) {
- var error = {message: message, fileName: script, lineNumber: line};
- if (opt_stack) {
- error['stack'] = opt_stack;
- }
- throw error;
- }
- function testsendErrorReport() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.sendErrorReport('message', 'filename.js', 123, 'trace');
- assertEquals(
- '/log?script=filename.js&error=message&line=123', MockXhrIo.lastUrl);
- assertEquals('trace=trace', MockXhrIo.lastContent);
- }
- function testsendErrorReportWithCustomSender() {
- var uri = null;
- var method = null;
- var content = null;
- var headers = null;
- function mockXhrSender(uriIn, methodIn, contentIn, headersIn) {
- uri = uriIn;
- method = methodIn;
- content = contentIn;
- headers = headersIn;
- }
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setXhrSender(mockXhrSender);
- errorReporter.sendErrorReport('message', 'filename.js', 123, 'trace');
- assertEquals('/log?script=filename.js&error=message&line=123', uri);
- assertEquals('POST', method);
- assertEquals('trace=trace', content);
- assertUndefined(headers);
- }
- function testsendErrorReport_noTrace() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.sendErrorReport('message', 'filename.js', 123);
- assertEquals(
- '/log?script=filename.js&error=message&line=123', MockXhrIo.lastUrl);
- assertEquals('', MockXhrIo.lastContent);
- }
- function test_nonInternetExplorerSendErrorReport() {
- if (goog.userAgent.product.SAFARI) {
- // TODO(b/20733468): Disabled so we can get the rest of the Closure test
- // suite running in a continuous build. Will investigate later.
- return;
- }
- stubs.set(goog.userAgent, 'IE', false);
- stubs.set(goog.global, 'setTimeout', function(fcn, time) { fcn.call(); });
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- var errorFunction = goog.partial(throwAnErrorWith, url, 5, 'Hello :)');
- try {
- goog.global.setTimeout(errorFunction, 0);
- } catch (e) {
- // Expected. The error is rethrown after sending.
- }
- assertEquals(
- '/errorreporter?script=' + encodedUrl + '&error=Hello%20%3A)&line=5',
- MockXhrIo.lastUrl);
- assertEquals('trace=Not%20available', MockXhrIo.lastContent);
- }
- function test_internetExplorerSendErrorReport() {
- stubs.set(goog.userAgent, 'IE', true);
- stubs.set(goog.userAgent, 'isVersionOrHigher', goog.functions.FALSE);
- // Remove test runner's onerror handler so the test doesn't fail.
- stubs.set(goog.global, 'onerror', null);
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- goog.global.onerror('Goodbye :(', url, 22);
- assertEquals(
- '/errorreporter?script=' + encodedUrl + '&error=Goodbye%20%3A(&line=22',
- MockXhrIo.lastUrl);
- assertEquals('trace=Not%20available', MockXhrIo.lastContent);
- }
- function test_setLoggingHeaders() {
- stubs.set(goog.userAgent, 'IE', true);
- stubs.set(goog.userAgent, 'isVersionOrHigher', goog.functions.FALSE);
- // Remove test runner's onerror handler so the test doesn't fail.
- stubs.set(goog.global, 'onerror', null);
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- errorReporter.setLoggingHeaders('header!');
- goog.global.onerror('Goodbye :(', 'http://www.your.tst/more/bogus.js', 22);
- assertEquals('header!', MockXhrIo.lastHeaders);
- }
- function test_nonInternetExplorerSendErrorReportWithTrace() {
- stubs.set(goog.userAgent, 'IE', false);
- stubs.set(goog.global, 'setTimeout', function(fcn, time) { fcn.call(); });
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- var trace = 'Error(\"Something Wrong\")@:0\n' +
- '$MF$E$Nx$([object Object])@http://a.b.c:83/a/f.js:901\n' +
- '([object Object])@http://a.b.c:813/a/f.js:37';
- var errorFunction = goog.partial(throwAnErrorWith, url, 5, 'Hello :)', trace);
- try {
- goog.global.setTimeout(errorFunction, 0);
- } catch (e) {
- // Expected. The error is rethrown after sending.
- }
- assertEquals(
- '/errorreporter?script=' + encodedUrl + '&error=Hello%20%3A)&line=5',
- MockXhrIo.lastUrl);
- assertEquals(
- 'trace=' +
- 'Error(%22Something%20Wrong%22)%40%3A0%0A' +
- '%24MF%24E%24Nx%24(%5Bobject%20Object%5D)%40' +
- 'http%3A%2F%2Fa.b.c%3A83%2Fa%2Ff.js%3A901%0A' +
- '(%5Bobject%20Object%5D)%40http%3A%2F%2Fa.b.c%3A813%2Fa%2Ff.js%3A37',
- MockXhrIo.lastContent);
- }
- function testProtectAdditionalEntryPoint_nonIE() {
- stubs.set(goog.userAgent, 'IE', false);
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- var fn = function() {};
- var protectedFn = errorReporter.protectAdditionalEntryPoint(fn);
- assertNotNull(protectedFn);
- assertNotEquals(fn, protectedFn);
- }
- function testProtectAdditionalEntryPoint_IE() {
- stubs.set(goog.userAgent, 'IE', true);
- stubs.set(goog.userAgent, 'isVersionOrHigher', goog.functions.FALSE);
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- var fn = function() {};
- var protectedFn = errorReporter.protectAdditionalEntryPoint(fn);
- assertNull(protectedFn);
- }
- function testHandleException_dispatchesEvent() {
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- var loggedErrors = 0;
- goog.events.listen(
- errorReporter, goog.debug.ErrorReporter.ExceptionEvent.TYPE,
- function(event) {
- assertNotNullNorUndefined(event.error);
- loggedErrors++;
- });
- errorReporter.handleException(new Error());
- errorReporter.handleException(new Error());
- assertEquals(
- 'Expected 2 errors. ' +
- '(Ensure an exception was not swallowed.)',
- 2, loggedErrors);
- }
- function testHandleException_includesContext() {
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- var loggedErrors = 0;
- var testError = new Error('test error');
- var testContext = {'contextParam': 'contextValue'};
- goog.events.listen(
- errorReporter, goog.debug.ErrorReporter.ExceptionEvent.TYPE,
- function(event) {
- assertNotNullNorUndefined(event.error);
- assertObjectEquals({contextParam: 'contextValue'}, event.context);
- loggedErrors++;
- });
- errorReporter.handleException(testError, testContext);
- assertEquals(
- 'Expected 1 error. ' +
- '(Ensure an exception was not swallowed.)',
- 1, loggedErrors);
- }
- function testContextProvider() {
- errorReporter = goog.debug.ErrorReporter.install(
- '/errorreporter',
- function(error, context) { context.providedContext = 'value'; });
- var loggedErrors = 0;
- var testError = new Error('test error');
- goog.events.listen(
- errorReporter, goog.debug.ErrorReporter.ExceptionEvent.TYPE,
- function(event) {
- assertNotNullNorUndefined(event.error);
- assertObjectEquals({providedContext: 'value'}, event.context);
- loggedErrors++;
- });
- errorReporter.handleException(testError);
- assertEquals(
- 'Expected 1 error. ' +
- '(Ensure an exception was not swallowed.)',
- 1, loggedErrors);
- }
- function testContextProvider_withOtherContext() {
- errorReporter = goog.debug.ErrorReporter.install(
- '/errorreporter',
- function(error, context) { context.providedContext = 'value'; });
- var loggedErrors = 0;
- var testError = new Error('test error');
- goog.events.listen(
- errorReporter, goog.debug.ErrorReporter.ExceptionEvent.TYPE,
- function(event) {
- assertNotNullNorUndefined(event.error);
- assertObjectEquals(
- {providedContext: 'value', otherContext: 'value'}, event.context);
- loggedErrors++;
- });
- errorReporter.handleException(testError, {'otherContext': 'value'});
- assertEquals(
- 'Expected 1 error. ' +
- '(Ensure an exception was not swallowed.)',
- 1, loggedErrors);
- }
- function testHandleException_ignoresExceptionsDuringEventDispatch() {
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- goog.events.listen(
- errorReporter, goog.debug.ErrorReporter.ExceptionEvent.TYPE,
- function(event) { fail('This exception should be swallowed.'); });
- errorReporter.handleException(new Error());
- }
- function testHandleException_doNotReportErrorToServer() {
- var error = new goog.debug.Error();
- error.reportErrorToServer = false;
- errorReporter.handleException(error);
- assertNull(MockXhrIo.lastUrl);
- }
- function testDisposal() {
- errorReporter = goog.debug.ErrorReporter.install('/errorreporter');
- if (!goog.userAgent.IE) {
- assertNotEquals(originalSetTimeout, window.setTimeout);
- }
- goog.dispose(errorReporter);
- assertEquals(originalSetTimeout, window.setTimeout);
- }
- function testSetContextPrefix() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setContextPrefix('baz.');
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals('trace=trace&baz.foo=bar', MockXhrIo.lastContent);
- }
- function testTruncationLimit() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setTruncationLimit(6);
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals('trace=', MockXhrIo.lastContent);
- }
- function testZeroTruncationLimit() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setTruncationLimit(0);
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals('', MockXhrIo.lastContent);
- }
- function testTruncationLimitLargerThanBody() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setTruncationLimit(9999);
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals('trace=trace&context.foo=bar', MockXhrIo.lastContent);
- }
- function testSetNegativeTruncationLimit() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- assertThrows(function() { errorReporter.setTruncationLimit(-10); });
- }
- function testSetTruncationLimitNull() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setTruncationLimit(null);
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals('trace=trace&context.foo=bar', MockXhrIo.lastContent);
- }
- function testAttemptAutoProtectWithAllowAutoProtectOff() {
- goog.debug.ErrorReporter.ALLOW_AUTO_PROTECT = false;
- assertThrows(function() {
- errorReporter =
- new goog.debug.ErrorReporter('/log', function(e, context) {}, false);
- });
- }
- function testSetAdditionalArgumentsArgsEmptyObject() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setAdditionalArguments({});
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals(
- '/log?script=filename.js&error=message&line=123', MockXhrIo.lastUrl);
- }
- function testSetAdditionalArgumentsSingleArgument() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setAdditionalArguments({'extra': 'arg'});
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals(
- '/log?script=filename.js&error=message&line=123&extra=arg',
- MockXhrIo.lastUrl);
- }
- function testSetAdditionalArgumentsMultipleArguments() {
- errorReporter = new goog.debug.ErrorReporter('/log');
- errorReporter.setAdditionalArguments({'extra': 'arg', 'cat': 'dog'});
- errorReporter.sendErrorReport(
- 'message', 'filename.js', 123, 'trace', {'foo': 'bar'});
- assertEquals(
- '/log?script=filename.js&error=message&line=123&extra=arg&cat=dog',
- MockXhrIo.lastUrl);
- }
|