我的应用程序中有一个函数,(对于一小部分用户,但每天都有少数人)引发一个似乎不可能的错误。从函数引发的错误来看,它看起来像'center' !== 'center'
。每次发生此错误都发生在Chrome上,第一次发生在2023年10月16日。用户遇到此错误一两次,然后它似乎自己解决了。
下面是该函数的简化版本。去掉了很多代码,但相关的控制流几乎完全相同。
function createBaseGradient(gradient) {
const start = gradient.start;
// ...
if (start === 'center') {
// ...
return '...'
}
// ...
if (start === 'left') {
// ...
} else if (start === 'top') {
// ...
} else if (start === 'bottom') {
// ...
} else if (start === 'right') {
// ...
} else {
internalError(
`Illegal gradient start (${JSON.stringify(start)}, ${encodeURIComponent(
start
)}, ${stringToCharCodes(
start
)}) of type ${typeof start}. Webworker: ${isWebWorker}. Valid gradient starts are: (${VALID_STARTS}, ${VALID_STARTS.map(
stringToCharCodes
)})`
);
}
// ...
return '...';
}
字符串
下面是我看到的一个错误的确切文本:
错误:非法梯度开始(“center”,center,99,101,110,116,101,114,END)类型字符串。Webworker:false。有效的渐变开始是:(中心,左上,左,左下,上,下,右上,右,右下,99,101,110,116,101,114,结束,108,101,102,116,45,116,111,112,结束,108,101,102,116、END、108、101、102、116、45、98、111、116、116、111、109、END、116、111、112、END、98、111、116、116、111、109、END、114、105、103、104、116、45、116、111、112、END、114、105、103、104、116、END、114、105、103、104、116、END、114、105、103、104、116、45、98、111、116、116、111、109,结束)
因此,常量start
是一个字符串,值为"center"
,字符串中的所有字符都与字符串"center"
中的字符相同,顺序相同。但是start === 'center'
不可能为真,因为我们没有输入第一个if语句并返回。
一些可能相关的细节:参数gradient
在此函数中使用之前在web worker中创建。gradient.start
从Brython字符串类型转换为JavaScript字符串。start
的其他值确实会发生此错误。
以下是我迄今为止尝试的方法:我添加了上面包含的详细日志记录。我尝试将函数中的所有字符串存储在常量中,并使用这些常量创建VALID_STARTS
数组,以防某些浏览器扩展修改字符串,但情况似乎并非如此。我添加了更多日志记录,上面没有包含,抛出一个错误,如果我们以某种方式进入start === 'center'
的情况下,并继续没有返回,但该错误从来没有触发。
我还尝试创建一个可能的Web Worker错误的最小示例(其中从Web Worker发布的字符串'abc'
可能不等于'abc'
)。我在我的计算机上运行了几百万次,但它从未产生过错误。第一个错误的日期与新的Chrome版本或我这端的任何相关部署不一致。我简要地浏览了Chrome中的开放错误,但看起来我在那里不会有好运。
我真的很感激听到关于如何解决这个bug的新观点,以及来自任何JS大师的见解。这个字符串可能不是字符串,尽管'string'
是typeof start
?我可能不小心修改了字符串原型并以某种方式打破了平等?我不知道下一步该看哪里。
这里有一个链接到这个函数的未经编辑的源代码,如果它会有帮助的话:https://pastebin.com/0hdqLjqH
非常感谢你的任何想法!
基于评论中建议的新信息:
我在if (start == 'center')
if语句之前记录了以下值。它们的结果在值旁边的注解中。
const a = start + '!'; // center!
const b = CENTER + '!!'; // center!!
const f = start == CENTER; // false
const c = start === CENTER; // false
const d = typeof start; // string
const e = start.toString() === CENTER.toString(); // true
const g = start.normalize('NFC') === CENTER.normalize('NFC'); // true
型
所以有进步!我还不清楚为什么调用.toString()
会有不同,或者当我们已经比较了每个字符代码时,规范化字符串会有什么不同,但我们现在实际上有一些事情要做。
1条答案
按热度按时间czfnxgou1#
这段代码看起来甚至不正确。变量不能和常量是同一个对象=。但是变量可以等于常量==。
字符串