-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Protect against ReferenceError when creating SharedWorker #20575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Protect against ReferenceError when creating SharedWorker #20575
Conversation
Some browsers do not have EventSource within the SharedWorker context even though it is available in the normal context. This leads to a global error percolating up to the main page. Here we simply wrap the new Source in a try/catch and catch the error falling back to a poller if so. Fix go-gitea#20572 Signed-off-by: Andrew Thornton <[email protected]>
const pollerFn = (timeout, lastCount) => { | ||
if (timeout <= 0) { | ||
return; | ||
} | ||
setTimeout(() => { | ||
const _promise = updateNotificationCountWithCallback(pollerFn, timeout, lastCount); | ||
}, timeout); | ||
}; | ||
|
||
pollerFn(notificationSettings.MinTimeout, notificationCount.text()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const pollerFn = (timeout, lastCount) => { | |
if (timeout <= 0) { | |
return; | |
} | |
setTimeout(() => { | |
const _promise = updateNotificationCountWithCallback(pollerFn, timeout, lastCount); | |
}, timeout); | |
}; | |
pollerFn(notificationSettings.MinTimeout, notificationCount.text()); | |
const timeout = notificationSettings.MinTimeout; | |
const lastCount = notificationCount.text(); | |
if (timeout <= 0) { | |
return; | |
} | |
setTimeout(() => { | |
const _promise = updateNotificationCountWithCallback(pollerFn, timeout, lastCount); | |
}, timeout); | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've got rid of the definition of the pollerfn in this suggestion and then you use it later.
What's the point of this change? Why are you redefining as a constant?
It's deliberately structured the way it's structured.
worker.addEventListener('error', (event) => { | ||
console.error(event); | ||
worker.addEventListener('error', (error) => { | ||
if (error.message && error.message === 'ReferenceError: EventSource is not defined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm absolutely not a fan of comparing against error messages, and even less of doing some strange behavior in that case.
At least add a comment, if comparing against a specific error is impossible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, it's not necessary to use the error message if the error can be detected by a stable method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the specific error? Where is the specific error defined in the specs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment #20575 (comment)
@@ -70,6 +87,10 @@ export function initNotificationCount() { | |||
if (event.data.type === 'notification-count') { | |||
const _promise = receiveUpdateCount(event.data); | |||
} else if (event.data.type === 'error') { | |||
if (event.data.message === 'unable to create Source: ReferenceError: EventSource is not defined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
worker.port.addEventListener('error', (e) => { | ||
console.error(e); | ||
worker.port.addEventListener('error', (error) => { | ||
if (error.message && error.message === 'unable to create Source: ReferenceError: EventSource is not defined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
const fn = (timeout) => { | ||
if (timeout <= 0) { | ||
return; | ||
} | ||
setTimeout(() => { | ||
const _promise = updateStopwatchWithCallback(fn, timeout); | ||
}, timeout); | ||
}; | ||
|
||
fn(notificationSettings.MinTimeout); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const fn = (timeout) => { | |
if (timeout <= 0) { | |
return; | |
} | |
setTimeout(() => { | |
const _promise = updateStopwatchWithCallback(fn, timeout); | |
}, timeout); | |
}; | |
fn(notificationSettings.MinTimeout); | |
const timeout = notificationSettings.MinTimeout; | |
if (timeout <= 0) { | |
return; | |
} | |
setTimeout(() => { | |
const _promise = updateStopwatchWithCallback(fn, timeout); | |
}, timeout); | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No this suggestion is wrong. You have dropped the definition of the fn that is being called.
worker.addEventListener('error', (event) => { | ||
console.error(event); | ||
worker.addEventListener('error', (error) => { | ||
if (error.message && error.message === 'ReferenceError: EventSource is not defined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
@@ -47,6 +70,10 @@ export function initStopwatch() { | |||
if (event.data.type === 'stopwatches') { | |||
updateStopwatchData(JSON.parse(event.data.data)); | |||
} else if (event.data.type === 'error') { | |||
if (event.data.message === 'unable to create Source: ReferenceError: EventSource is not defined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
worker.port.addEventListener('error', (e) => { | ||
console.error(e); | ||
worker.port.addEventListener('error', (error) => { | ||
if (error.message && error.message === 'ReferenceError: EventSource is not defined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
IMO the root problem here is that the SharedWorker doesn't have EventSource support. Since the EventSource is only used by So, maybe there could be a one-line fix for it (then no need to poll in real-time since the browser is non-standard? and the real-time polling never worked before for such non-standard browsers?). self.addEventListener('connect', (e) => {
// return early if there is no EventSource in SharedWorker
if (!self.EventSource) return;
...
} Or: port.addEventListener('message', (event) => {
...
...
if (!self.EventSource) {
// Tell the caller to use poller clearly, but it's still more complex than before
// I still prefer the one-line fix above, because the real-time polling never worked before 😆
port.postMessage({type: 'use-poller'});
} else {
source = new Source(url);
...
}
} |
@wxiaoguang I think you have misunderstood what the purpose of the pollerfn is. Here the error is such that the source will not work so the pollerfn is called to replace update notifications instead. There is no polling to check if the source is working. |
I understand it correctly. So the second suggestion is to make a |
You need to be in the shared worker context to check if the eventsource is available. |
It will work, it's already in the context. The context I have tested |
Fine do it then. |
I thought that's your honor to do so ........ |
Some browsers do not have EventSource within the SharedWorker context even though
it is available in the normal context. This leads to a global error percolating
up to the main page.
Here we simply wrap the new Source in a try/catch and catch the error falling back
to a poller if so.
Fix #20572
Signed-off-by: Andrew Thornton [email protected]