Merge pull request #33152 from backstage/rugvip/use-api-holder-no-throw
frontend-plugin-api: change `useApiHolder` to not throw outside API context
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/frontend-plugin-api': patch
|
||||
'@backstage/core-plugin-api': patch
|
||||
---
|
||||
|
||||
Changed `useApiHolder` to return an empty `ApiHolder` instead of throwing when used outside of an API context.
|
||||
@@ -114,12 +114,16 @@ describe('ApiProvider', () => {
|
||||
withLogCollector(['error'], () => {
|
||||
expect(() => {
|
||||
render(<MyHookConsumer />);
|
||||
}).toThrow(/^API context is not available/);
|
||||
}).toThrow('No implementation available for apiRef{x}');
|
||||
}).error,
|
||||
).toEqual([
|
||||
expect.stringContaining('Error: API context is not available'),
|
||||
expect.stringContaining(
|
||||
'Error: No implementation available for apiRef{x}',
|
||||
),
|
||||
expect.objectContaining({ type: 'unhandled-exception' }),
|
||||
expect.stringContaining('Error: API context is not available'),
|
||||
expect.stringContaining(
|
||||
'Error: No implementation available for apiRef{x}',
|
||||
),
|
||||
expect.objectContaining({ type: 'unhandled-exception' }),
|
||||
expect.stringContaining(
|
||||
'The above error occurred in the <MyHookConsumer> component',
|
||||
@@ -130,12 +134,16 @@ describe('ApiProvider', () => {
|
||||
withLogCollector(['error'], () => {
|
||||
expect(() => {
|
||||
render(<MyHocConsumer />);
|
||||
}).toThrow(/^API context is not available/);
|
||||
}).toThrow('No implementation available for apiRef{x}');
|
||||
}).error,
|
||||
).toEqual([
|
||||
expect.stringContaining('Error: API context is not available'),
|
||||
expect.stringContaining(
|
||||
'Error: No implementation available for apiRef{x}',
|
||||
),
|
||||
expect.objectContaining({ type: 'unhandled-exception' }),
|
||||
expect.stringContaining('Error: API context is not available'),
|
||||
expect.stringContaining(
|
||||
'Error: No implementation available for apiRef{x}',
|
||||
),
|
||||
expect.objectContaining({ type: 'unhandled-exception' }),
|
||||
expect.stringContaining(
|
||||
'The above error occurred in the <withApis(Component)> component',
|
||||
|
||||
@@ -17,7 +17,30 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { createVersionedContextForTesting } from '@backstage/version-bridge';
|
||||
import { createApiRef } from './ApiRef';
|
||||
import { useApi } from './useApi';
|
||||
import { useApi, useApiHolder } from './useApi';
|
||||
|
||||
describe('useApiHolder', () => {
|
||||
const context = createVersionedContextForTesting('api-context');
|
||||
|
||||
afterEach(() => {
|
||||
context.reset();
|
||||
});
|
||||
|
||||
it('should return the API holder from context', () => {
|
||||
const holder = { get: jest.fn() };
|
||||
context.set({ 1: holder });
|
||||
|
||||
const renderedHook = renderHook(() => useApiHolder());
|
||||
expect(renderedHook.result.current).toBe(holder);
|
||||
});
|
||||
|
||||
it('should return an empty API holder when there is no context', () => {
|
||||
const renderedHook = renderHook(() => useApiHolder());
|
||||
|
||||
const holder = renderedHook.result.current;
|
||||
expect(holder.get(createApiRef<string>({ id: 'x' }))).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('useApi', () => {
|
||||
const context = createVersionedContextForTesting('api-context');
|
||||
|
||||
@@ -19,6 +19,8 @@ import { ApiRef, ApiHolder, TypesToApiRefs } from './types';
|
||||
import { useVersionedContext } from '@backstage/version-bridge';
|
||||
import { NotImplementedError } from '@backstage/errors';
|
||||
|
||||
const emptyApiHolder: ApiHolder = Object.freeze({ get: () => undefined });
|
||||
|
||||
/**
|
||||
* React hook for retrieving {@link ApiHolder}, an API catalog.
|
||||
*
|
||||
@@ -27,7 +29,7 @@ import { NotImplementedError } from '@backstage/errors';
|
||||
export function useApiHolder(): ApiHolder {
|
||||
const versionedHolder = useVersionedContext<{ 1: ApiHolder }>('api-context');
|
||||
if (!versionedHolder) {
|
||||
throw new NotImplementedError('API context is not available');
|
||||
return emptyApiHolder;
|
||||
}
|
||||
|
||||
const apiHolder = versionedHolder.atVersion(1);
|
||||
|
||||
Reference in New Issue
Block a user