@react-native-windows/telemetry
Advanced tools
Comparing version 0.76.0 to 0.76.1
@@ -39,2 +39,9 @@ "use strict"; | ||
const versionUtils = __importStar(require("../utils/versionUtils")); | ||
class CustomTestError extends Error { | ||
constructor(message) { | ||
super(message); | ||
this.name = 'CustomTestError'; | ||
this.errno = '123'; | ||
} | ||
} | ||
class TelemetryTest extends telemetry_1.Telemetry { | ||
@@ -322,3 +329,9 @@ /** Run at the beginning of each test. */ | ||
: 'Unknown'); | ||
expect(codedError.data).toStrictEqual((_a = expectedError.data) !== null && _a !== void 0 ? _a : {}); | ||
// If the exception type is not CodedError but any data got copied into envelope.CodedError.data, | ||
// for instance autolinking error info, build the expected CodedError.data. | ||
let expectedCodedErrorData = {}; | ||
if (expectedError instanceof CustomTestError) { | ||
expectedCodedErrorData = { errno: expectedError.errno }; | ||
} | ||
expect(codedError.data).toStrictEqual((_a = expectedError.data) !== null && _a !== void 0 ? _a : expectedCodedErrorData); | ||
} | ||
@@ -491,2 +504,74 @@ else { | ||
}); | ||
test.each(testTelemetryOptions)('A custom Error-based object with MS Build error info is copied into codedError.data appropriately by trackException()', async (options) => { | ||
await TelemetryTest.startTest(options); | ||
const expectedError = new CustomTestError('some message'); | ||
// AI eats errors thrown in telemetry processors | ||
const caughtErrors = []; | ||
TelemetryTest.addTelemetryInitializer(verifyTestCommandTelemetryProcessor(caughtErrors, 'Unknown', expectedError)); | ||
await runTestCommandE2E(() => testCommandBody(expectedError)); | ||
TelemetryTest.endTest(() => { | ||
// Check if any errors were thrown | ||
expect(caughtErrors).toHaveLength(0); | ||
}); | ||
}); | ||
test.each(testTelemetryOptions)('Telemetry run test command end to end with CodedError, verifies PII is scrubbed if present in CodedError.', async (options) => { | ||
await TelemetryTest.startTest(options); | ||
const codedErrorInfo = new errorUtils.CodedError('MSBuildError', // type | ||
'test error', // message | ||
{ | ||
fieldWithPath: 'Test Error occurred at C:\\some\\file\\path\\project.build.appxrecipe', | ||
fieldWithNoPath: 'Test Error data', | ||
fieldWithNoString: 14, | ||
arrayField: [ | ||
'No path', | ||
15, | ||
'Clean this path: C:\\some\\file\\path2\\project.build.appxrecipe', | ||
[ | ||
'No path', | ||
150, | ||
'Also clean this: C:\\some\\file\\path2\\project.build.appxrecipe', | ||
], | ||
], | ||
someObject: { | ||
fieldWithPath: 'Test Error occurred at C:\\some\\file\\path3\\project.build.appxrecipe', | ||
fieldWithNoPath: 'Test Error data 2', | ||
fieldWithNoString: 16, | ||
nestedObject: { | ||
fieldWithPath: 'Test Error occurred at C:\\some\\file\\path4\\project.build.appxrecipe', | ||
fieldWithNoPath: 'Test Error data 3', | ||
fieldWithNoString: 17, // expectation: no changes to this value. | ||
}, | ||
}, | ||
}); | ||
const expectedError = new errorUtils.CodedError('MSBuildError', // type | ||
'test error', // message | ||
{ | ||
fieldWithPath: 'Test Error occurred at [path]', | ||
fieldWithNoPath: 'Test Error data', | ||
fieldWithNoString: 14, | ||
arrayField: [ | ||
'No path', | ||
15, | ||
'Clean this path: [path]', | ||
['No path', 150, 'Also clean this: [path]'], | ||
], | ||
someObject: { | ||
fieldWithPath: 'Test Error occurred at [path]', | ||
fieldWithNoPath: 'Test Error data 2', | ||
fieldWithNoString: 16, | ||
nestedObject: { | ||
fieldWithPath: 'Test Error occurred at [path]', | ||
fieldWithNoPath: 'Test Error data 3', | ||
fieldWithNoString: 17, | ||
}, | ||
}, | ||
}); | ||
const caughtErrors = []; | ||
TelemetryTest.addTelemetryInitializer(verifyTestCommandTelemetryProcessor(caughtErrors, expectedError.type, expectedError)); | ||
await runTestCommandE2E(() => testCommandBody(codedErrorInfo)); | ||
TelemetryTest.endTest(() => { | ||
// Check if any errors were thrown | ||
expect(caughtErrors).toHaveLength(0); | ||
}); | ||
}); | ||
//# sourceMappingURL=telemetry.test.js.map |
@@ -73,3 +73,4 @@ /** | ||
static convertErrorIntoExceptionData(error: Error): Record<string, any>; | ||
static sanitizeAny(data: any): any; | ||
} | ||
export {}; |
@@ -37,2 +37,3 @@ "use strict"; | ||
const errorUtils = __importStar(require("./utils/errorUtils")); | ||
const nameUtils = __importStar(require("./utils/nameUtils")); | ||
// 1DS instrumentation key | ||
@@ -184,6 +185,10 @@ const RNW_1DS_INSTRUMENTATION_KEY = '49ff6d3ef12f4578a7b75a2573d9dba8-026332b2-2d50-452f-ad0d-50f921c97a9d-7145'; | ||
} | ||
if (forceRefresh === true || !Telemetry.versionsProp[name]) { | ||
// Process the package name to comply with the backend requirements | ||
const packageName = nameUtils.isValidTelemetryPackageName(name) | ||
? name | ||
: nameUtils.cleanTelemetryPackageName(name); | ||
if (forceRefresh === true || !Telemetry.versionsProp[packageName]) { | ||
const value = await getValue(); | ||
if (value) { | ||
Telemetry.versionsProp[name] = value; | ||
Telemetry.versionsProp[packageName] = value; | ||
return true; | ||
@@ -338,5 +343,7 @@ } | ||
if (error[f]) { | ||
codedErrorStruct.data.codedError.data[f] = error[f]; | ||
codedErrorStruct.data[f] = error[f]; | ||
} | ||
} | ||
// Scrub any potential PII present in codedError.data array, as long as the data is a string. | ||
codedErrorStruct.data = Telemetry.sanitizeAny(codedErrorStruct.data); | ||
// Break down TS Error object into Exception Data | ||
@@ -393,2 +400,24 @@ const exceptionData = Telemetry.convertErrorIntoExceptionData(error); | ||
} | ||
static sanitizeAny(data) { | ||
if (Array.isArray(data)) { | ||
// This is an array, sanitize each element recursively. | ||
return data.map(item => Telemetry.sanitizeAny(item)); | ||
} | ||
else if (typeof data === 'object' && data !== null) { | ||
// This is an object, sanitize each field recursively. | ||
const sanitizedObject = {}; | ||
for (const key in data) { | ||
if (Object.prototype.hasOwnProperty.call(data, key)) { | ||
sanitizedObject[key] = Telemetry.sanitizeAny(data[key]); | ||
} | ||
} | ||
return sanitizedObject; | ||
} | ||
else if (typeof data === 'string') { | ||
// The base case: this is a string, sanitize it. | ||
return errorUtils.sanitizeErrorMessage(data); | ||
} | ||
// Not a string, return the data unchanged. | ||
return data; | ||
} | ||
} | ||
@@ -395,0 +424,0 @@ Telemetry.appInsightsCore = undefined; |
{ | ||
"name": "@react-native-windows/telemetry", | ||
"version": "0.76.0", | ||
"version": "0.76.1", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "main": "lib-commonjs/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
307312
50
3122