diff --git a/src/core/client/admin/routes/AuthCheck/AuthCheckRoute.tsx b/src/core/client/admin/routes/AuthCheck/AuthCheckRoute.tsx index 3f46f0364..ab912c939 100644 --- a/src/core/client/admin/routes/AuthCheck/AuthCheckRoute.tsx +++ b/src/core/client/admin/routes/AuthCheck/AuthCheckRoute.tsx @@ -10,6 +10,7 @@ import { GQLUSER_ROLE } from "coral-framework/schema"; import { AuthCheckRouteQueryResponse } from "coral-admin/__generated__/AuthCheckRouteQuery.graphql"; +import NetworkError from "./NetworkError"; import RestrictedContainer from "./RestrictedContainer"; interface Props { @@ -17,6 +18,7 @@ interface Props { router: Router; setRedirectPath: MutationProp; data: AuthCheckRouteQueryResponse; + error: Error | null; } type CheckParams = @@ -86,6 +88,9 @@ function createAuthCheckRoute(check: CheckParams) { } public render() { + if (this.props.error) { + return ; + } if (!this.props.data || this.shouldRedirectTo()) { return null; } diff --git a/src/core/client/admin/routes/AuthCheck/NetworkError.css b/src/core/client/admin/routes/AuthCheck/NetworkError.css new file mode 100644 index 000000000..eb4d5153b --- /dev/null +++ b/src/core/client/admin/routes/AuthCheck/NetworkError.css @@ -0,0 +1,3 @@ +.root { + padding: 20px; +} diff --git a/src/core/client/admin/routes/AuthCheck/NetworkError.tsx b/src/core/client/admin/routes/AuthCheck/NetworkError.tsx new file mode 100644 index 000000000..45e8d1a93 --- /dev/null +++ b/src/core/client/admin/routes/AuthCheck/NetworkError.tsx @@ -0,0 +1,20 @@ +import { Localized } from "fluent-react/compat"; +import React, { FunctionComponent } from "react"; + +import { Message } from "coral-ui/components"; + +import styles from "./NetworkError.css"; + +const NetworkError: FunctionComponent<{}> = () => { + return ( +
+ + + A network error occurred. Please refresh the page + + +
+ ); +}; + +export default NetworkError; diff --git a/src/core/client/framework/lib/network/createNetwork.ts b/src/core/client/framework/lib/network/createNetwork.ts index 672ab3b0e..25e61b187 100644 --- a/src/core/client/framework/lib/network/createNetwork.ts +++ b/src/core/client/framework/lib/network/createNetwork.ts @@ -56,6 +56,11 @@ export default function createNetwork( retryDelays: (attempt: number) => Math.pow(2, attempt + 4) * 100, // or simple array [3200, 6400, 12800, 25600, 51200, 102400, 204800, 409600], statusCodes: [500, 503, 504], + beforeRetry: ({ abort, attempt }) => { + if (attempt > 2) { + abort(); + } + }, }), authMiddleware({ token: tokenGetter, diff --git a/src/locales/en-US/admin.ftl b/src/locales/en-US/admin.ftl index 6e99e7fbf..2ad76f281 100644 --- a/src/locales/en-US/admin.ftl +++ b/src/locales/en-US/admin.ftl @@ -856,5 +856,4 @@ hotkeysModal-shortcuts-reject = Reject hotkeysModal-shortcuts-ban = Ban comment author hotkeysModal-shortcuts-zen = Toggle single-comment view - - +authcheck-network-error = A network error occurred. Please refresh the page. diff --git a/src/types/react-relay-network-modern.d.ts b/src/types/react-relay-network-modern.d.ts index 1746d6e91..f6c1fc189 100644 --- a/src/types/react-relay-network-modern.d.ts +++ b/src/types/react-relay-network-modern.d.ts @@ -282,6 +282,17 @@ declare module "react-relay-network-modern/es" { res: RelayResponse ) => boolean; + export type AbortFn = (msg?: string) => any; + + export type BeforeRetryCb = (meta: { + forceRetry: Function; + abort: AbortFn; + delay: number; + attempt: number; + lastError: Error | null; + req: RelayRequestAny; + }) => any; + export interface RetryMiddlewareOpts { fetchTimeout?: number; retryDelays?: number[] | RetryAfterFn; @@ -290,6 +301,7 @@ declare module "react-relay-network-modern/es" { allowMutations?: boolean; allowFormData?: boolean; forceRetry?: ForceRetryFn | false; + beforeRetry?: BeforeRetryCb | false; } export const retryMiddleware: (opts?: RetryMiddlewareOpts) => Middleware;