diff --git a/packages/core-app-api/src/apis/system/ApiProvider.test.tsx b/packages/core-app-api/src/apis/system/ApiProvider.test.tsx index c80b0c117f..f3a0a67263 100644 --- a/packages/core-app-api/src/apis/system/ApiProvider.test.tsx +++ b/packages/core-app-api/src/apis/system/ApiProvider.test.tsx @@ -115,11 +115,11 @@ describe('ApiProvider', () => { withLogCollector(['error'], () => { expect(() => { render(); - }).toThrow(/^No provider available for api-context context/); + }).toThrow(/^API context is not available/); }).error, ).toEqual([ expect.stringMatching( - /^Error: Uncaught \[Error: No provider available for api-context context/, + /^Error: Uncaught \[Error: API context is not available/, ), expect.stringMatching( /^The above error occurred in the component/, @@ -130,11 +130,11 @@ describe('ApiProvider', () => { withLogCollector(['error'], () => { expect(() => { render(); - }).toThrow(/^No provider available for api-context context/); + }).toThrow(/^API context is not available/); }).error, ).toEqual([ expect.stringMatching( - /^Error: Uncaught \[Error: No provider available for api-context context/, + /^Error: Uncaught \[Error: API context is not available/, ), expect.stringMatching( /^The above error occurred in the component/, diff --git a/packages/core-plugin-api/src/apis/system/useApi.tsx b/packages/core-plugin-api/src/apis/system/useApi.tsx index 10fe1df4a7..ef598a4c0e 100644 --- a/packages/core-plugin-api/src/apis/system/useApi.tsx +++ b/packages/core-plugin-api/src/apis/system/useApi.tsx @@ -20,6 +20,9 @@ import { useVersionedContext } from '@backstage/version-bridge'; export function useApiHolder(): ApiHolder { const versionedHolder = useVersionedContext<{ 1: ApiHolder }>('api-context'); + if (!versionedHolder) { + throw new Error('API context is not available'); + } const apiHolder = versionedHolder.atVersion(1); if (!apiHolder) { diff --git a/packages/core-plugin-api/src/app/useApp.tsx b/packages/core-plugin-api/src/app/useApp.tsx index d4615eb532..05d2e1c5c0 100644 --- a/packages/core-plugin-api/src/app/useApp.tsx +++ b/packages/core-plugin-api/src/app/useApp.tsx @@ -20,6 +20,10 @@ import { AppContext as AppContextV1 } from './types'; export const useApp = (): AppContextV1 => { const versionedContext = useVersionedContext<{ 1: AppContextV1 }>('app-context'); + if (!versionedContext) { + throw new Error('App context is not available'); + } + const appContext = versionedContext.atVersion(1); if (!appContext) { throw new Error('AppContext v1 not available'); diff --git a/packages/core-plugin-api/src/routing/useRouteRef.tsx b/packages/core-plugin-api/src/routing/useRouteRef.tsx index 56c5baff8e..ea05cc14fd 100644 --- a/packages/core-plugin-api/src/routing/useRouteRef.tsx +++ b/packages/core-plugin-api/src/routing/useRouteRef.tsx @@ -50,6 +50,10 @@ export function useRouteRef( const sourceLocation = useLocation(); const versionedContext = useVersionedContext<{ 1: RouteResolver }>('routing-context'); + if (!versionedContext) { + throw new Error('Routing context is not available'); + } + const resolver = versionedContext.atVersion(1); const routeFunc = useMemo( () => resolver && resolver.resolve(routeRef, sourceLocation), diff --git a/packages/version-bridge/api-report.md b/packages/version-bridge/api-report.md index 9f653a11d9..367c2da102 100644 --- a/packages/version-bridge/api-report.md +++ b/packages/version-bridge/api-report.md @@ -36,7 +36,7 @@ export function useVersionedContext< Versions extends { [version in number]: any; }, ->(key: string): VersionedValue; +>(key: string): VersionedValue | undefined; // @public export type VersionedValue< diff --git a/packages/version-bridge/src/lib/VersionedContext.test.tsx b/packages/version-bridge/src/lib/VersionedContext.test.tsx index bbd924780d..659fd9b5b9 100644 --- a/packages/version-bridge/src/lib/VersionedContext.test.tsx +++ b/packages/version-bridge/src/lib/VersionedContext.test.tsx @@ -65,13 +65,9 @@ describe('VersionedContext', () => { const rendered = renderHook(() => useVersionedContext('test-context-3')); - expect(() => rendered.result.current).toThrow( - 'Global test-context-3 is not set', - ); + expect(rendered.result.current).toBeUndefined(); context.set({ 1: '3v1' }); - expect(() => rendered.result.current).toThrow( - 'Global test-context-3 is not set', - ); + expect(rendered.result.current).toBeUndefined(); // should need a rerender before update rendered.rerender(); @@ -86,9 +82,7 @@ describe('VersionedContext', () => { context.reset(); rendered.rerender(); - expect(() => rendered.result.current).toThrow( - 'Global test-context-3 is not set', - ); + expect(rendered.result.current).toBeUndefined(); context.set({ 1: '3v1', 2: '3v2' }); diff --git a/packages/version-bridge/src/lib/VersionedContext.ts b/packages/version-bridge/src/lib/VersionedContext.ts index 4a08739c16..ecf7ab46e6 100644 --- a/packages/version-bridge/src/lib/VersionedContext.ts +++ b/packages/version-bridge/src/lib/VersionedContext.ts @@ -15,7 +15,7 @@ */ import { createContext, useContext, Context } from 'react'; -import { getGlobalSingleton, getOrCreateGlobalSingleton } from './globalObject'; +import { getOrCreateGlobalSingleton } from './globalObject'; import { createVersionedValueMap, VersionedValue } from './VersionedValue'; /** @@ -55,6 +55,10 @@ export function createVersionedContext< * ```ts * const versionedHolder = useVersionedContext<{ 1: string }>('my-context'); * + * if (!versionedHolder) { + * throw new Error('My context is not available!') + * } + * * const myValue = versionedHolder.atVersion(1); * * // ... @@ -62,14 +66,8 @@ export function createVersionedContext< */ export function useVersionedContext< Versions extends { [version in number]: any }, ->(key: string): VersionedValue { - const versionedValue = useContext( - getGlobalSingleton>>(key), - ); - if (!versionedValue) { - throw new Error(`No provider available for ${key} context`); - } - return versionedValue; +>(key: string): VersionedValue | undefined { + return useContext(createVersionedContext(key)); } /**