Skip to content

Commit

Permalink
[BUG] DebugPlugin - helpers.js:334 Uncaught TypeError: Cannot convert…
Browse files Browse the repository at this point in the history
… a Symbol value to a string #1602
  • Loading branch information
MSNev committed Jul 6, 2021
1 parent 3e1f041 commit 902806d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { arrForEach, arrIndexOf, hasOwnProperty, isFunction, isObject, isString, objKeys } from '@microsoft/applicationinsights-core-js';
import { arrForEach, arrIndexOf, hasOwnProperty, isFunction, isObject, isString, isSymbol, objKeys } from '@microsoft/applicationinsights-core-js';
import { Util } from '@microsoft/applicationinsights-common';
import { strShimPrototype } from '@microsoft/applicationinsights-shims';

Expand Down Expand Up @@ -38,20 +38,25 @@ export function traverseAndReplace(target: Object, maxDepth: number, currentDept
}
if (isObject(target)) {
for (const key of getTargetKeys(target, excludedKeys, includeFunctions)) {
if (target[key] !== null && arrIndexOf(thingsReferenced, target[key]) !== -1) {
out[key] = `<circular (${key} - "${getTargetName(target[key])}")>`;
let targetValue = target[key];
if (isSymbol(targetValue)) {
targetValue = targetValue.toString();
}
else if (target[key] !== null && isObject(target[key])) {

if (targetValue !== null && arrIndexOf(thingsReferenced, targetValue) !== -1) {
out[key] = `<circular (${key} - "${getTargetName(targetValue)}")>`;
}
else if (targetValue !== null && isObject(targetValue)) {
if (currentDepth >= maxDepth) {
out[key] = '<max allowed depth reached>';
} else {
thingsReferenced.push(target);
out[key] = traverseAndReplace(target[key], maxDepth, currentDepth + 1, thingsReferenced, excludedKeys, includeFunctions);
out[key] = traverseAndReplace(targetValue, maxDepth, currentDepth + 1, thingsReferenced, excludedKeys, includeFunctions);
thingsReferenced.pop();
}
}
else {
out[key] = target[key];
out[key] = targetValue;
}
}
}
Expand Down Expand Up @@ -184,13 +189,29 @@ export function getTargetName(target: any) {
// Look like a prototype
return target.name || "";
}

return ((target[strConstructor]) || {}).name || "";
}

return "";
}

function _toString(value: any) {
if (isString(value)) {
return value;
}

if (isSymbol(value)) {
return value.toString();
}

if (isFunction(value["toString"])) {
return (value["toString"] as any)() || "";
}

return "";
}

export function getTargetKeys(target: any, excludedKeys: string[], includeFunctions: boolean) {
let keys: string[] = objKeys(target);

Expand All @@ -201,10 +222,11 @@ export function getTargetKeys(target: any, excludedKeys: string[], includeFuncti
let propKeys = Object[strGetOwnPropertyNames](target);
if (propKeys) {
arrForEach(propKeys, (key) => {
if (keys.indexOf(key) === -1) {
const theKey = _toString(key);
if (theKey && keys.indexOf(theKey) === -1) {
keys.push(key);
}
})
});
}
}
} catch (ex) {
Expand All @@ -215,12 +237,14 @@ export function getTargetKeys(target: any, excludedKeys: string[], includeFuncti

let theKeys: string[] = [];
arrForEach(keys, (key) => {

if (!includeFunctions && isFunction(target[key])) {
return;
}

if (excludedKeys.indexOf(key) === -1) {
theKeys.push(key);
const theKey = _toString(key);
if (theKey && excludedKeys.indexOf(theKey) === -1) {
theKeys.push(theKey);
}
});

Expand Down Expand Up @@ -270,6 +294,12 @@ export function formatLogElements(target: Object, tmLabel: string, key: string,
if (excludeKeys.indexOf(key) !== -1) {
continue;
}

let targetValue = target[key];
if (isSymbol(targetValue)) {
targetValue = targetValue.toString();
}

if (key === '<maxdepth>') {
const builder = document.createElement("div");
builder.className = 'empty';
Expand All @@ -283,15 +313,15 @@ export function formatLogElements(target: Object, tmLabel: string, key: string,
builder.innerText = '<empty>';
children.push(builder);
}
else if (target[key] !== null && arrIndexOf(thingsReferenced, target[key]) !== -1) {
else if (targetValue !== null && arrIndexOf(thingsReferenced, targetValue) !== -1) {
const builder = document.createElement("div");
builder.className = 'empty';
builder.innerText = `<circular (${key}) - "${getTargetName(target[key])}">`;
builder.innerText = `<circular (${key}) - "${getTargetName(targetValue)}">`;
children.push(builder);
}
else if (target[key] !== null && (isObject(target[key]) || Util.isError(target[key]))) {
else if (targetValue !== null && (isObject(targetValue) || Util.isError(targetValue))) {
thingsReferenced.push(target);
let formatted = formatLogElements(target[key], null, key, level + 1, textFilter, excludeKeys, thingsReferenced, includeFunctions);
let formatted = formatLogElements(targetValue, null, key, level + 1, textFilter, excludeKeys, thingsReferenced, includeFunctions);
thingsReferenced.pop();
if (formatted.matched) {
childOpened = true;
Expand Down Expand Up @@ -328,16 +358,16 @@ export function formatLogElements(target: Object, tmLabel: string, key: string,
outerSpan.appendChild(keySpan);

const valueSpan = document.createElement("span");
if (isFunction(target[key])) {
const fnStr = target[key].toString();
if (isFunction(targetValue)) {
const fnStr = targetValue.toString();
const fnHead = fnStr.match(/^([^{]+)/)[1];
valueSpan.textContent = `${fnHead}{...}`;
} else {
if (_setInnerText(valueSpan, `${target[key]}`, textFilter)) {
if (_setInnerText(valueSpan, `${targetValue}`, textFilter)) {
childOpened = true;
}
}
valueSpan.className = `${typeof target[key]}`;
valueSpan.className = `${typeof targetValue}`;
outerSpan.appendChild(valueSpan);
builder.appendChild(outerSpan);
children.push(builder);
Expand Down
10 changes: 10 additions & 0 deletions shared/AppInsightsCore/src/JavaScriptSDK/HelperFuncs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ export function isBoolean(value: any): value is boolean {
return typeof value === "boolean";
}

/**
* Checks if the type of value is a Symbol.
* This only returns a boolean as returning value is Symbol will cause issues for older TypeScript consumers
* @param {any} value - Value to be checked.
* @return {boolean} True if the value is a Symbol, false otherwise.
*/
export function isSymbol(value: any): boolean {
return typeof value === "symbol";
}

/**
* Convert a date to I.S.O. format in IE8
*/
Expand Down
2 changes: 1 addition & 1 deletion shared/AppInsightsCore/src/applicationinsights-core-js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export {
export {
isTypeof, isUndefined, isNullOrUndefined, hasOwnProperty, isObject, isFunction, attachEvent, detachEvent, normalizeJsName,
objForEachKey, strEndsWith, strStartsWith, isDate, isArray, isError, isString, isNumber, isBoolean, toISOString, arrForEach, arrIndexOf,
arrMap, arrReduce, strTrim, objKeys, objDefineAccessors, dateNow, getExceptionName, throwError, strContains,
arrMap, arrReduce, strTrim, objKeys, objDefineAccessors, dateNow, getExceptionName, throwError, strContains, isSymbol,
setValue, getSetValue, isNotTruthy, isTruthy, proxyAssign, createClassFromInterface, optimizeObject, isNotUndefined, isNotNullOrUndefined,
objFreeze, objSeal
} from './JavaScriptSDK/HelperFuncs';
Expand Down

0 comments on commit 902806d

Please sign in to comment.