Closed Madriix closed 5 months ago
Hm, that's odd. It's a fairly recent version of iOS as well (15.6).
The line that's throwing is this one:
Unfortunately, without a test to reproduce, I don't know why showRootNode.getElementById
is undefined.
Does this only occur on iOS 15? Have you been able to reproduce the error yourself? Is it running as a WebView in a native app, as a homescreen app, in Safari...?
Well I tested if shadowRoot.getElementById
is supported in iOS 15.5, and it is:
So I'm sorry, but I'm totally stumped. :confused:
Here are other user agents affected:
errorMsg : TypeError: shadowRootNode.getElementById is not a function. (In 'shadowRootNode.getElementById(
emo-${emoji.id}
)', 'shadowRootNode.getElementById' is undefined) errorUrl : https://x.com/v1/others/emoji-picker-element/picker.js errorLine : 1203 errorCol : 66 errorStack : "emojiToDomNode@https://x.com/v1/others/emoji-picker-element/picker.js:1203:66\ncheckZwjSupport@https://x.com/v1/others/emoji-picker-element/picker.js:296:35\ncheckZwjSupportAndUpdate@https://x.com/v1/others/emoji-picker-element/picker.js:1204:20" userAgent : Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1Date : 2024/02/17 01:59:06 errorMsg : TypeError: shadowRootNode.getElementById is not a function. (In 'shadowRootNode.getElementById(
emo-${emoji.id}
)', 'shadowRootNode.getElementById' is undefined) errorUrl : https://x.com/v1/others/emoji-picker-element/picker.js errorLine : 1203 errorCol : 66 errorStack : "emojiToDomNode@https://x.com/v1/others/emoji-picker-element/picker.js:1203:66\ncheckZwjSupport@https://x.com/v1/others/emoji-picker-element/picker.js:296:35\ncheckZwjSupportAndUpdate@https://x.com/v1/others/emoji-picker-element/picker.js:1204:20" userAgent : Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/121.0.6167.171 Mobile/15E148 Safari/604.1
The debug is generated with a window.onerror
on a production location. Since this morning, in 12 hours it has detected 205 errors linked to the log that I showed you. I haven't tested with an iPhone. Users are not on an application, but on their browser, probably Safari.
Sorry, but this doesn't really help me narrow it down. getRootNode
should always return either a Document
or ShadowRoot
, and so I don't understand how its getElementById
can be undefined:
Are users reporting any visual errors in the component itself? Or are you just seeing this error in your logs?
Also: which version of emoji-picker-element
are you using? I just released v1.21.1 which probably won't fix your issue, but will at least give us a different error message that may help debug.
I updated. But I think I found the problem. Here are the explanations:
1) I use this script:
<script type="module">
async function hasIDB() {
if (typeof indexedDB === 'undefined') {
return false
}
try {
const idbFailed = await new Promise(resolve => {
const db = indexedDB.open('test-idb')
db.onerror = () => resolve(true)
db.onsuccess = () => {
indexedDB.deleteDatabase('test-idb')
resolve(false)
}
})
if (idbFailed) {
return false
}
} catch (e) {
return false
}
return true
}
async function polyfillIDB() {
await import('/v1/others/test/fake-indexeddb.js?v=1708213879284')
// Can't override the indexedDB global, but we can monkey-patch it
for (const func of ['open', 'deleteDatabase']) {
indexedDB[func] = FakeIndexedDB[func].bind(FakeIndexedDB)
}
for (const func of ['bound', 'lowerBound', 'upperBound', 'only']) {
IDBKeyRange[func] = FDBKeyRange[func].bind(FDBKeyRange)
}
}
(async () => {
if (!(await hasIDB())) {
await polyfillIDB()
}
const {Picker} = await import('/v1/others/emoji-picker-element/index.js?v=1708213879284')
//const picker = new Picker()
//document.body.appendChild(picker)
})()
</script>
2) The menu is then called but not in the mobile version:
- I don't use the emoji menu on the mobile version, because They manage to have emojis via their keyboard for certain people.The code to detect mobile and non-mobile that I use:
function is_mobile_width() {
const n = navigator;
if (n && n.userAgentData && n.userAgentData.mobile) {
return true;
}
else if (document.body.clientWidth <= 950) {
return true;
}
else {
return false;
}
}
So in the end, the thing I should do is not to call the first script in the mobile version. Currently the first script is global, for all users. Sorry for bothering you for nothing.
Interesting. I still don't understand how this caused shadowRootNode.getElementById
to not be a function? But if you think the problem is with your app instead of emoji-picker-element
then I'm happy to close this issue. Thanks for reporting!
Hey @nolanlawson!
I'm encountering this issue as well.
D.getElementById is not a function. (In 'D.getElementById(`emo-${X.id}`)', 'D.getElementById' is undefined)
User-Agent: Mobile Safari UI/WKWebView
iOS Version: 17.2.1
It seems to happen intermittently. I haven't been able to replicate it locally but I can provide some context from Sentry errors.
Thanks for your awesome library!
Hm that's really bizarre. @aerovulpe I suppose you're using the latest version of the package? But Sentry doesn't give you the un-minified stacktrace? And you're also only seeing this on iOS Safari?
I upgraded to 1.21.1
from 1.20.1
before dropping a comment. I haven't seen a Sentry error related to shadowRootNode.getElementById
since the upgrade, so I think https://github.com/nolanlawson/emoji-picker-element/commit/19331c6be6de9da9199a43c6aa13e48fd310a952 may have fixed it!
Unfortunately, I don't have the un-minified stack trace, and it only affected certain iOS Safari users, but it seems the issue has been fixed empirically.
I'll keep monitoring, and I'll let you know if anything pops open, but it's probably safe to reclose this.
Thanks again!
Sounds good! Please reopen if the issue crops up again in 1.21.1.
iOS users often have this error:
It only does this with iOS