[ide-react] Handle failed socket.io loading (#16265)

GitOrigin-RevId: 3a460e1f53387e7012f994f6e8ea9ce764eb0fd2
This commit is contained in:
Alf Eaton 2023-12-15 12:21:00 +00:00 committed by Copybot
parent 56d70a18ae
commit 1ce16dd09f
6 changed files with 56 additions and 20 deletions

View file

@ -54,16 +54,38 @@ export const Loading: FC<{
}
}, [projectJoined])
const error =
connectionState.error ||
(i18n.error ? getMeta('ol-translationLoadErrorMessage') : '')
const LoadingScreenError = () => {
if (connectionState.error) {
// NOTE: translations not ready yet
return connectionState.error === 'io-not-loaded'
? 'Could not connect to websocket server :('
: connectionState.error
}
if (i18n.error) {
return getMeta('ol-translationLoadErrorMessage')
}
return ''
}
// Use loading text from the server, because i18n will not be ready initially
const label = getMeta('ol-loadingText')
const hasError = Boolean(connectionState.error || i18n.error)
return (
<div className="loading-screen">
<LoadingBranded loadProgress={progress} label={label} error={error} />
<LoadingBranded
loadProgress={progress}
label={label}
hasError={hasError}
/>
{hasError && (
<p className="loading-screen-error">
<LoadingScreenError />
</p>
)}
</div>
)
}

View file

@ -67,6 +67,18 @@ export class ConnectionManager extends Emitter<Events> {
}) as unknown as Socket
this.socket = socket
// bail out if socket.io failed to load (e.g. the real-time server is down)
if (typeof window.io !== 'object') {
debugConsole.error(
'Socket.io javascript not loaded. Please check that the real-time service is running and accessible.'
)
this.changeState({
...this.state,
error: 'io-not-loaded',
})
return
}
socket.on('disconnect', () => this.onDisconnect())
socket.on('error', () => this.onConnectError())
socket.on('connect_failed', () => this.onConnectError())

View file

@ -7,6 +7,7 @@ export type ConnectionError =
| 'rate-limited'
| 'unable-to-connect'
| 'unable-to-join'
| 'io-not-loaded'
export type ConnectionState = {
readyState: WebSocket['CONNECTING'] | WebSocket['OPEN'] | WebSocket['CLOSED']

View file

@ -71,9 +71,11 @@ function ProjectListPageContent() {
eventTracking.sendMB('loads_v2_dash', {})
}, [])
const { t } = useTranslation()
return isLoading ? (
<div className="loading-container">
<LoadingBranded loadProgress={loadProgress} />
<LoadingBranded loadProgress={loadProgress} label={t('loading')} />
</div>
) : (
<>

View file

@ -1,28 +1,26 @@
import { useTranslation } from 'react-i18next'
type LoadingBrandedTypes = {
loadProgress: number // Percentage
label?: string
error?: string | null
hasError?: boolean
}
export default function LoadingBranded({
loadProgress,
label,
error,
hasError = false,
}: LoadingBrandedTypes) {
const { t } = useTranslation()
return (
<div className="loading-screen-brand-container">
<div
className="loading-screen-brand"
style={{ height: `${loadProgress}%` }}
/>
{error ? (
<p className="loading-screen-error">{error}</p>
) : (
<>
<div className="loading-screen-brand-container">
<div
className="loading-screen-brand"
style={{ height: `${loadProgress}%` }}
/>
</div>
{!hasError && (
<div className="h3 loading-screen-label" aria-live="polite">
{label || t('loading')}
{label}
<span className="loading-screen-ellip" aria-hidden="true">
.
</span>
@ -34,6 +32,6 @@ export default function LoadingBranded({
</span>
</div>
)}
</div>
</>
)
}

View file

@ -43,5 +43,6 @@ declare global {
}
expectingLinkedFileRefreshedSocketFor?: string | null
writefull?: any
io?: any
}
}