Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 2x 3x 3x 1x 2x 2x | import ConnectionErrorNotice from '../../components/connection-error-notice';
import useConnection from '../../components/use-connection';
import useRestoreConnection from '../../hooks/use-restore-connection';
import { resolveConnectionErrorActions } from './resolve-actions';
import type {
ConnectionErrorMap,
ConnectionErrorObject,
ConnectionErrorProps,
UseConnectionErrorNoticeResult,
} from './types';
import type { ReactElement } from 'react';
export type {
ConnectionErrorAudience,
ConnectionErrorData,
ConnectionErrorMap,
ConnectionErrorObject,
} from './types';
/**
* Connection error notice hook.
*
* The single source of truth for user-facing connection errors. It surfaces
* real WPCOM-reported errors from the store (`connectionErrors`) and resolves
* them into ready-to-render `actions`, so consumers render resolved CTAs
* instead of re-deriving copy/handlers themselves. Pass the same options
* accepted by `<ConnectionError />` to customize action handlers, tracking and
* navigation.
*
* @param {ConnectionErrorProps} options - Action resolution options.
* @return {UseConnectionErrorNoticeResult} - The hook data, including resolved `actions`.
*/
export default function useConnectionErrorNotice( {
actionHandlers = {},
trackingCallback = null,
customActions = null,
reconnectTrackingEvent,
navigate,
includeHealthErrors = false,
}: ConnectionErrorProps = {} ): UseConnectionErrorNoticeResult {
const { connectionErrors, connectionHealthErrors } = useConnection( {} );
const { restoreConnection, isRestoringConnection, restoreConnectionError } =
useRestoreConnection();
// connectionErrors is typed as Array<string|object> but is actually a nested
// object at runtime; the store selector can also fall back to `[]`. Normalize
// to a map so the returned value is honest to the ConnectionErrorMap contract.
const storedErrorMap: ConnectionErrorMap =
connectionErrors && typeof connectionErrors === 'object' && ! Array.isArray( connectionErrors )
? ( connectionErrors as unknown as ConnectionErrorMap )
: {};
// `connectionHealthErrors` is typed as a `ConnectionErrorMap` at the store
// boundary (selector defaults to `{}`, never an array), so no normalization
// is needed — just guard against a caller that never populated the slot.
// Only consumers that opted in (i.e. actually ran the probe) inherit it; for
// everyone else the shared health slot is invisible.
const healthErrorMap: ConnectionErrorMap = includeHealthErrors
? connectionHealthErrors ?? {}
: {};
// Precedence: real WPCOM-reported store errors win; health-check failures are
// the fallback so a broken connection still surfaces when the store is empty.
const errorMap: ConnectionErrorMap = Object.keys( storedErrorMap ).length
? storedErrorMap
: healthErrorMap;
const connectionErrorList = Object.values( errorMap ).shift();
const firstError: ConnectionErrorObject | undefined =
connectionErrorList && Object.values( connectionErrorList ).length
? Object.values( connectionErrorList ).shift()
: undefined;
const connectionErrorMessage = firstError?.error_message;
const hasConnectionError = Boolean( connectionErrorMessage );
const actions = firstError
? resolveConnectionErrorActions( firstError, {
actionHandlers,
trackingCallback,
customActions,
restoreConnection,
isRestoringConnection,
reconnectTrackingEvent,
navigate,
} )
: [];
return {
hasConnectionError,
connectionErrorMessage,
connectionError: firstError, // Full error object with error_type, etc.
connectionErrors: errorMap, // All errors for advanced use cases.
actions, // Resolved CTA actions for the connection error.
restoreConnection,
isRestoringConnection,
restoreConnectionError,
};
}
export const ConnectionError = ( {
context,
...props
}: ConnectionErrorProps = {} ): ReactElement | null => {
const {
hasConnectionError,
connectionErrorMessage,
connectionError,
actions,
restoreConnection,
isRestoringConnection,
restoreConnectionError,
} = useConnectionErrorNotice( props );
if ( ! hasConnectionError ) {
return null;
}
// An explicit 'none' action marks the error as informational only, so the
// default "Restore Connection" fallback must not be shown either.
const suppressRestoreFallback = connectionError?.error_data?.action === 'none';
return (
<ConnectionErrorNotice
isRestoringConnection={ isRestoringConnection }
restoreConnectionError={ restoreConnectionError }
restoreConnectionCallback={
actions.length === 0 && ! suppressRestoreFallback ? restoreConnection : null
}
message={ connectionErrorMessage }
context={ context }
actions={ actions }
/>
);
};
|