Просмотр исходного кода

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

GitOrigin-RevId: 3a460e1f53387e7012f994f6e8ea9ce764eb0fd2
Alf Eaton 2 лет назад
Родитель
Сommit
1ce16dd09f

+ 26 - 4
services/web/frontend/js/features/ide-react/components/loading.tsx

@@ -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>
   )
 }

+ 12 - 0
services/web/frontend/js/features/ide-react/connection/connection-manager.ts

@@ -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())

+ 1 - 0
services/web/frontend/js/features/ide-react/connection/types/connection-state.ts

@@ -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']

+ 3 - 1
services/web/frontend/js/features/project-list/components/project-list-root.tsx

@@ -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>
   ) : (
     <>

+ 13 - 15
services/web/frontend/js/shared/components/loading-branded.tsx

@@ -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>
+    </>
   )
 }

+ 1 - 0
services/web/types/window.ts

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