Skip to content

Commit 5bf67ec

Browse files
committed
Protect against ReferenceError when creating SharedWorker
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]>
1 parent ff9b6fa commit 5bf67ec

File tree

3 files changed

+76
-32
lines changed

3 files changed

+76
-32
lines changed

web_src/js/features/eventsource.sharedworker.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,18 @@ self.addEventListener('connect', (e) => {
9393
}
9494
}
9595
// Create a new Source
96-
source = new Source(url);
97-
source.register(port);
98-
sourcesByUrl[url] = source;
99-
sourcesByPort[port] = source;
96+
try {
97+
source = new Source(url);
98+
source.register(port);
99+
sourcesByUrl[url] = source;
100+
sourcesByPort[port] = source;
101+
} catch (error) {
102+
port.postMessage({
103+
type: 'error',
104+
message: `unable to create Source: ${error}`,
105+
});
106+
port.close();
107+
}
100108
} else if (event.data.type === 'listen') {
101109
const source = sourcesByPort[port];
102110
source.listen(event.data.eventType);

web_src/js/features/notification.js

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,28 @@ export function initNotificationCount() {
4949
return;
5050
}
5151

52+
const poller = () => {
53+
const pollerFn = (timeout, lastCount) => {
54+
if (timeout <= 0) {
55+
return;
56+
}
57+
setTimeout(() => {
58+
const _promise = updateNotificationCountWithCallback(pollerFn, timeout, lastCount);
59+
}, timeout);
60+
};
61+
62+
pollerFn(notificationSettings.MinTimeout, notificationCount.text());
63+
};
64+
5265
if (notificationSettings.EventSourceUpdateTime > 0 && !!window.EventSource && window.SharedWorker) {
5366
// Try to connect to the event source via the shared worker first
5467
const worker = new SharedWorker(`${__webpack_public_path__}js/eventsource.sharedworker.js`, 'notification-worker');
55-
worker.addEventListener('error', (event) => {
56-
console.error(event);
68+
worker.addEventListener('error', (error) => {
69+
if (error.message && error.message === 'ReferenceError: EventSource is not defined') {
70+
poller();
71+
return;
72+
}
73+
console.error(error);
5774
});
5875
worker.port.addEventListener('messageerror', () => {
5976
console.error('Unable to deserialize message');
@@ -70,6 +87,10 @@ export function initNotificationCount() {
7087
if (event.data.type === 'notification-count') {
7188
const _promise = receiveUpdateCount(event.data);
7289
} else if (event.data.type === 'error') {
90+
if (event.data.message === 'unable to create Source: ReferenceError: EventSource is not defined') {
91+
poller();
92+
return;
93+
}
7394
console.error(event.data);
7495
} else if (event.data.type === 'logout') {
7596
if (event.data.data !== 'here') {
@@ -87,8 +108,11 @@ export function initNotificationCount() {
87108
worker.port.close();
88109
}
89110
});
90-
worker.port.addEventListener('error', (e) => {
91-
console.error(e);
111+
worker.port.addEventListener('error', (error) => {
112+
if (error.message && error.message === 'unable to create Source: ReferenceError: EventSource is not defined') {
113+
return;
114+
}
115+
console.error(error);
92116
});
93117
worker.port.start();
94118
window.addEventListener('beforeunload', () => {
@@ -97,21 +121,14 @@ export function initNotificationCount() {
97121
});
98122
worker.port.close();
99123
});
100-
101124
return;
102125
}
103126

104127
if (notificationSettings.MinTimeout <= 0) {
105128
return;
106129
}
107130

108-
const fn = (timeout, lastCount) => {
109-
setTimeout(() => {
110-
const _promise = updateNotificationCountWithCallback(fn, timeout, lastCount);
111-
}, timeout);
112-
};
113-
114-
fn(notificationSettings.MinTimeout, notificationCount.text());
131+
poller();
115132
}
116133

117134
async function updateNotificationCountWithCallback(callback, timeout, lastCount) {

web_src/js/features/stopwatch.js

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,34 @@ export function initStopwatch() {
2626
$(this).parent().trigger('submit');
2727
});
2828

29+
const poller = () => {
30+
const fn = (timeout) => {
31+
if (timeout <= 0) {
32+
return;
33+
}
34+
setTimeout(() => {
35+
const _promise = updateStopwatchWithCallback(fn, timeout);
36+
}, timeout);
37+
};
38+
39+
fn(notificationSettings.MinTimeout);
40+
41+
const currSeconds = $('.stopwatch-time').data('seconds');
42+
if (currSeconds) {
43+
updateTimeInterval = updateStopwatchTime(currSeconds);
44+
}
45+
};
46+
47+
2948
if (notificationSettings.EventSourceUpdateTime > 0 && !!window.EventSource && window.SharedWorker) {
3049
// Try to connect to the event source via the shared worker first
3150
const worker = new SharedWorker(`${__webpack_public_path__}js/eventsource.sharedworker.js`, 'notification-worker');
32-
worker.addEventListener('error', (event) => {
33-
console.error(event);
51+
worker.addEventListener('error', (error) => {
52+
if (error.message && error.message === 'ReferenceError: EventSource is not defined') {
53+
poller();
54+
return;
55+
}
56+
console.error(error);
3457
});
3558
worker.port.addEventListener('messageerror', () => {
3659
console.error('Unable to deserialize message');
@@ -47,6 +70,10 @@ export function initStopwatch() {
4770
if (event.data.type === 'stopwatches') {
4871
updateStopwatchData(JSON.parse(event.data.data));
4972
} else if (event.data.type === 'error') {
73+
if (event.data.message === 'unable to create Source: ReferenceError: EventSource is not defined') {
74+
poller();
75+
return;
76+
}
5077
console.error(event.data);
5178
} else if (event.data.type === 'logout') {
5279
if (event.data.data !== 'here') {
@@ -64,8 +91,11 @@ export function initStopwatch() {
6491
worker.port.close();
6592
}
6693
});
67-
worker.port.addEventListener('error', (e) => {
68-
console.error(e);
94+
worker.port.addEventListener('error', (error) => {
95+
if (error.message && error.message === 'ReferenceError: EventSource is not defined') {
96+
return;
97+
}
98+
console.error(error);
6999
});
70100
worker.port.start();
71101
window.addEventListener('beforeunload', () => {
@@ -82,18 +112,7 @@ export function initStopwatch() {
82112
return;
83113
}
84114

85-
const fn = (timeout) => {
86-
setTimeout(() => {
87-
const _promise = updateStopwatchWithCallback(fn, timeout);
88-
}, timeout);
89-
};
90-
91-
fn(notificationSettings.MinTimeout);
92-
93-
const currSeconds = $('.stopwatch-time').data('seconds');
94-
if (currSeconds) {
95-
updateTimeInterval = updateStopwatchTime(currSeconds);
96-
}
115+
poller();
97116
}
98117

99118
async function updateStopwatchWithCallback(callback, timeout) {

0 commit comments

Comments
 (0)