Showing details in case of CORS exception
This commit is contained in:
Родитель
0c34a1db62
Коммит
a90e49b604
|
@ -34,14 +34,14 @@ class UtilTests extends TestClass {
|
|||
// mock cookies
|
||||
((document) => {
|
||||
var cookies = {};
|
||||
document.__defineGetter__('cookie', () => {
|
||||
document.__defineGetter__('cookie',() => {
|
||||
var output = [];
|
||||
for (var cookieName in cookies) {
|
||||
output.push(cookieName + "=" + cookies[cookieName]);
|
||||
}
|
||||
return output.join(";");
|
||||
});
|
||||
document.__defineSetter__('cookie', (s) => {
|
||||
document.__defineSetter__('cookie',(s) => {
|
||||
var indexOfSeparator = s.indexOf("=");
|
||||
var key = s.substr(0, indexOfSeparator);
|
||||
var value = s.substring(indexOfSeparator + 1);
|
||||
|
@ -93,7 +93,7 @@ class UtilTests extends TestClass {
|
|||
this.testCase({
|
||||
name: "UtilTests: new GUID",
|
||||
test: () => {
|
||||
sinon.stub(Math, "random", () => 0);
|
||||
sinon.stub(Math, "random",() => 0);
|
||||
var expected = "00000000-0000-4000-8000-000000000000";
|
||||
var actual = Microsoft.ApplicationInsights.Util.newGuid();
|
||||
Assert.equal(expected, actual, "expected guid was generated");
|
||||
|
@ -163,7 +163,7 @@ class UtilTests extends TestClass {
|
|||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault(null) === false);
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault("") === false);
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault("asdf") === false);
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault(0) === false);
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault(0) === false);
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault({ asfd: "sdf" }) === false);
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault(new Object()) === false);
|
||||
|
||||
|
@ -171,6 +171,16 @@ class UtilTests extends TestClass {
|
|||
Assert.ok(Microsoft.ApplicationInsights.Util.stringToBoolOrDefault("TrUe") === true);
|
||||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: "UtilTests: isCrossOriginError",
|
||||
test: () => {
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.isCrossOriginError("Script error.", "", 0, 0, null) === true);
|
||||
|
||||
Assert.ok(Microsoft.ApplicationInsights.Util.isCrossOriginError("Script error.", "http://microsoft.com", 0, 0, null)
|
||||
=== false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
new UtilTests().registerTests();
|
|
@ -32,6 +32,39 @@ module Microsoft.ApplicationInsights.Telemetry {
|
|||
this.handledAt = handledAt || "unhandled";
|
||||
this.exceptions = [new _ExceptionDetails(exception)];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a simple exception with 1 stack frame. Useful for manual constracting of exception.
|
||||
*/
|
||||
public static CreateSimpleException(message: string, typeName: string, assembly: string, fileName: string,
|
||||
details: string, line: number, handledAt?: string): Telemetry.Exception {
|
||||
|
||||
// We can't override constructors, so throwing a fake error to use existing constructor and override all fields after that.
|
||||
var exceptionTelemetry;
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
exceptionTelemetry = new Telemetry.Exception(e);
|
||||
}
|
||||
|
||||
var stack = exceptionTelemetry.exceptions[0].parsedStack[0];
|
||||
stack.assembly = assembly;
|
||||
stack.fileName = fileName;
|
||||
stack.level = 0;
|
||||
stack.line = line;
|
||||
stack.method = "unknown";
|
||||
|
||||
var exception = exceptionTelemetry.exceptions[0];
|
||||
exception.hasFullStack = true;
|
||||
exception.message = message;
|
||||
exception.parsedStack = null;
|
||||
exception.stack = details;
|
||||
exception.typeName = typeName;
|
||||
exceptionTelemetry.handledAt = handledAt || "unhandled";
|
||||
|
||||
return exceptionTelemetry;
|
||||
}
|
||||
}
|
||||
|
||||
class _ExceptionDetails extends AI.ExceptionDetails implements ISerializable {
|
||||
|
@ -45,7 +78,7 @@ module Microsoft.ApplicationInsights.Telemetry {
|
|||
stack: false,
|
||||
parsedStack: []
|
||||
};
|
||||
|
||||
|
||||
constructor(exception: Error) {
|
||||
super();
|
||||
this.typeName = Common.DataSanitizer.sanitizeString(exception.name);
|
||||
|
|
|
@ -135,5 +135,17 @@
|
|||
|
||||
return hour + ":" + min + ":" + sec + "." + ms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if error has no meaningful data inside. Ususally such errors are received by window.onerror when error
|
||||
* happens in a script from other domain (cross origin, CORS).
|
||||
*/
|
||||
public static isCrossOriginError(message: string, url: string, lineNumber: number, columnNumber: number, error: Error): boolean {
|
||||
return (message == "Script error." || message == "Script error")
|
||||
&& url == ""
|
||||
&& lineNumber == 0
|
||||
&& columnNumber == 0
|
||||
&& error == null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ module Microsoft.ApplicationInsights {
|
|||
emitLineDelimitedJson: () => this.config.emitLineDelimitedJson,
|
||||
maxBatchSizeInBytes: () => this.config.maxBatchSizeInBytes,
|
||||
maxBatchInterval: () => this.config.maxBatchInterval,
|
||||
disableTelemetry: () => this.config.disableTelemetry
|
||||
disableTelemetry: () => this.config.disableTelemetry
|
||||
}
|
||||
|
||||
this.context = new ApplicationInsights.TelemetryContext(configGetters);
|
||||
|
@ -311,6 +311,21 @@ module Microsoft.ApplicationInsights {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In case of CORS exceptions - construct an exception manually.
|
||||
* See this for more info: http://stackoverflow.com/questions/5913978/cryptic-script-error-reported-in-javascript-in-chrome-and-firefox
|
||||
*/
|
||||
private SendCORSException() {
|
||||
var exceptionData = Microsoft.ApplicationInsights.Telemetry.Exception.CreateSimpleException(
|
||||
"Script error.", "Error", "unknown", "unknown",
|
||||
"There is no details for this exception because it violated browser’s same-origin policy. For cross-domain error reporting you can use crossorigtin attribute together with appropriate CORS HTTP headers. For more information please see http://www.w3.org/TR/cors/",
|
||||
0, null);
|
||||
|
||||
var data = new ApplicationInsights.Telemetry.Common.Data<ApplicationInsights.Telemetry.Exception>(Telemetry.Exception.dataType, exceptionData);
|
||||
var envelope = new Telemetry.Common.Envelope(data, Telemetry.Exception.envelopeType);
|
||||
this.context.track(envelope);
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom error handler for Application Insights
|
||||
* @param {string} message - The error message
|
||||
|
@ -321,21 +336,28 @@ module Microsoft.ApplicationInsights {
|
|||
*/
|
||||
public _onerror(message: string, url: string, lineNumber: number, columnNumber: number, error: Error) {
|
||||
try {
|
||||
if (!Util.isError(error)) {
|
||||
// ensure that we have an error object (browser may not pass an error i.e safari)
|
||||
try {
|
||||
throw new Error(message);
|
||||
} catch (exception) {
|
||||
error = exception;
|
||||
if (!error["stack"]) {
|
||||
error["stack"] = "@" + url + ":" + lineNumber + ":" + (columnNumber || 0);
|
||||
if (Util.isCrossOriginError(message, url, lineNumber, columnNumber, error)) {
|
||||
this.SendCORSException();
|
||||
} else {
|
||||
if (!Util.isError(error)) {
|
||||
// ensure that we have an error object (browser may not pass an error i.e safari)
|
||||
try {
|
||||
throw new Error(message);
|
||||
} catch (exception) {
|
||||
error = exception;
|
||||
if (!error["stack"]) {
|
||||
error["stack"] = "@" + url + ":" + lineNumber + ":" + (columnNumber || 0);
|
||||
}
|
||||
}
|
||||
|
||||
this.trackException(error);
|
||||
}
|
||||
}
|
||||
|
||||
this.trackException(error);
|
||||
} catch (exception) {
|
||||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "_onerror threw an exception: " + JSON.stringify(exception) + " while logging error: " + error.name + ", " + error.message);
|
||||
var errorString =
|
||||
error ? (error.name + ", " + error.message) : "null";
|
||||
|
||||
_InternalLogging.throwInternalNonUserActionable(LoggingSeverity.CRITICAL, "_onerror threw an exception: " + JSON.stringify(exception) + " while logging error: " + errorString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче