-
Notifications
You must be signed in to change notification settings - Fork 427
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sanity): add config for onUncaughtError (#7553)
### Description Adds ability to callback when an error happens and allows developers to add custom error telemetry (for example) I will drop the throw errors before merging, those are for testing purposes ### What to review - Does the code make sense? - Does the naming of the callback make sense? - I tried in other places, however, while discussing it with others in the team after not finding a place that would have context for the `useSource`, the current place where it exists seems to be the better option. If you all have any other suggestions I'd love to hear it! ### Testing Automated tests are in place. You can also manually trigger it by adding `throw new error("oh no new error)` within the `imageInput` or the `studioComponents` and then going to the `custom-components/structure` workspace and seeing the console logs work ### Notes for release Adds ability to callback when an error happens and allows developers to use errors thrown by the studio --------- Co-authored-by: Bjørge Næss <[email protected]>
- Loading branch information
Showing
19 changed files
with
372 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
packages/sanity/src/core/form/studio/FormBuilderInputErrorBoundary.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import {beforeAll, describe, expect, it, jest} from '@jest/globals' | ||
import {render, screen} from '@testing-library/react' | ||
import {type SanityClient} from 'sanity' | ||
|
||
import {createMockSanityClient} from '../../../../test/mocks/mockSanityClient' | ||
import {createTestProvider} from '../../../../test/testUtils/TestProvider' | ||
import {FormBuilderInputErrorBoundary} from './FormBuilderInputErrorBoundary' | ||
|
||
jest.mock('use-hot-module-reload', () => ({ | ||
useHotModuleReload: jest.fn(), | ||
})) | ||
|
||
describe('FormBuilderInputErrorBoundary', () => { | ||
beforeAll(() => { | ||
jest.clearAllMocks() | ||
}) | ||
|
||
it('renders children when there is no error', async () => { | ||
render( | ||
<FormBuilderInputErrorBoundary> | ||
<div data-testid="child">Child Component</div> | ||
</FormBuilderInputErrorBoundary>, | ||
) | ||
|
||
expect(screen.getByTestId('child')).toBeInTheDocument() | ||
}) | ||
|
||
it('calls onUncaughtError when an error is caught', async () => { | ||
const onUncaughtError = jest.fn() | ||
|
||
const ThrowErrorComponent = () => { | ||
throw new Error('An EXPECTED, testing error occurred!') | ||
} | ||
|
||
const client = createMockSanityClient() as unknown as SanityClient | ||
|
||
const TestProvider = await createTestProvider({ | ||
client, | ||
config: { | ||
name: 'default', | ||
projectId: 'test', | ||
dataset: 'test', | ||
onUncaughtError, | ||
}, | ||
}) | ||
|
||
render( | ||
<TestProvider> | ||
<FormBuilderInputErrorBoundary> | ||
<ThrowErrorComponent /> | ||
</FormBuilderInputErrorBoundary> | ||
</TestProvider>, | ||
) | ||
|
||
expect(onUncaughtError).toHaveBeenCalledTimes(1) | ||
}) | ||
}) |
3 changes: 2 additions & 1 deletion
3
packages/sanity/src/core/form/studio/FormBuilderInputErrorBoundary.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
.../sanity/src/core/studio/components/navbar/search/components/filters/filter/FilterForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
packages/sanity/src/core/studio/workspaceLoader/WorkspaceLoader.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
packages/sanity/src/core/studio/workspaceLoader/WorkspaceRouterProvider.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import {describe, expect, it, jest} from '@jest/globals' | ||
import {render, screen} from '@testing-library/react' | ||
import {type SanityClient, type Workspace} from 'sanity' | ||
|
||
import {createMockSanityClient} from '../../../../test/mocks/mockSanityClient' | ||
import {createTestProvider} from '../../../../test/testUtils/TestProvider' | ||
import {WorkspaceRouterProvider} from './WorkspaceRouterProvider' | ||
|
||
jest.mock('../router/RouterHistoryContext', () => ({ | ||
useRouterHistory: () => ({ | ||
location: {pathname: '/'}, | ||
listen: jest.fn(), | ||
}), | ||
})) | ||
|
||
jest.mock('../router', () => ({ | ||
createRouter: () => ({ | ||
getBasePath: jest.fn(), | ||
decode: jest.fn(), | ||
isNotFound: jest.fn(), | ||
}), | ||
})) | ||
|
||
jest.mock('sanity/router', () => ({ | ||
RouterProvider: ({children}: {children: React.ReactNode}) => <div>{children}</div>, | ||
IntentLink: () => <div>IntentLink</div>, | ||
})) | ||
|
||
jest.mock('./WorkspaceRouterProvider', () => ({ | ||
...(jest.requireActual('./WorkspaceRouterProvider') as object), | ||
useRouterFromWorkspaceHistory: jest.fn(), | ||
})) | ||
|
||
describe('WorkspaceRouterProvider', () => { | ||
const LoadingComponent = () => <div>Loading...</div> | ||
const children = <div>Children</div> | ||
const workspace = { | ||
basePath: '', | ||
tools: [], | ||
icon: null, | ||
unstable_sources: [], | ||
scheduledPublishing: false, | ||
document: {}, | ||
form: {}, | ||
search: {}, | ||
title: 'Default Workspace', | ||
name: 'default', | ||
projectId: 'test', | ||
dataset: 'test', | ||
schema: {}, | ||
templates: {}, | ||
currentUser: {}, | ||
authenticated: true, | ||
auth: {}, | ||
getClient: jest.fn(), | ||
i18n: {}, | ||
__internal: {}, | ||
type: 'workspace', | ||
// Add other required properties with appropriate default values | ||
} as unknown as Workspace | ||
|
||
it('renders children when state is not null', () => { | ||
render( | ||
<WorkspaceRouterProvider LoadingComponent={LoadingComponent} workspace={workspace}> | ||
{children} | ||
</WorkspaceRouterProvider>, | ||
) | ||
|
||
expect(screen.getByText('Children')).toBeInTheDocument() | ||
}) | ||
|
||
it('calls onUncaughtError when an error is caught', async () => { | ||
const onUncaughtError = jest.fn() | ||
|
||
const ThrowErrorComponent = () => { | ||
throw new Error('An EXPECTED, testing error occurred!') | ||
} | ||
|
||
const client = createMockSanityClient() as unknown as SanityClient | ||
|
||
const TestProvider = await createTestProvider({ | ||
client, | ||
config: { | ||
name: 'default', | ||
projectId: 'test', | ||
dataset: 'test', | ||
onUncaughtError, | ||
}, | ||
}) | ||
|
||
try { | ||
render( | ||
<TestProvider> | ||
{/* prevents thrown error from breaking the test */} | ||
<WorkspaceRouterProvider LoadingComponent={LoadingComponent} workspace={workspace}> | ||
<ThrowErrorComponent /> | ||
</WorkspaceRouterProvider> | ||
</TestProvider>, | ||
) | ||
} catch { | ||
expect(onUncaughtError).toHaveBeenCalledTimes(1) | ||
} | ||
}) | ||
}) |
Oops, something went wrong.