Skip to content
This repository has been archived by the owner on Feb 8, 2020. It is now read-only.

Commit

Permalink
fix: show error if an action was not handled
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Jan 1, 2020
1 parent 282f62c commit 0252bdc
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 5 deletions.
2 changes: 1 addition & 1 deletion jest/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const error = console.error;

console.error = (...args) =>
// Supress error messages regarding error boundary in tests
/Consider adding an error boundary to your tree to customize error handling behavior/m.test(
/(Consider adding an error boundary to your tree to customize error handling behavior|React will try to recreate this component tree from scratch using the error boundary you provided|Error boundaries should implement getDerivedStateFromError)/m.test(
args[0]
)
? void 0
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ it("doesn't update state if action wasn't handled", () => {

const onStateChange = jest.fn();

const spy = jest.spyOn(console, 'error').mockImplementation();

render(
<NavigationContainer onStateChange={onStateChange}>
<TestNavigator initialRouteName="foo">
Expand All @@ -367,6 +369,12 @@ it("doesn't update state if action wasn't handled", () => {
);

expect(onStateChange).toBeCalledTimes(0);

expect(spy.mock.calls[0][0]).toMatch(
"The action 'INVALID' with payload 'undefined' was not handled by any navigator."
);

spy.mockRestore();
});

it('cleans up state when the navigator unmounts', () => {
Expand Down
11 changes: 9 additions & 2 deletions packages/core/src/__tests__/useOnAction.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,7 @@ it("action doesn't bubble if target is specified", () => {
expect(onStateChange).not.toBeCalled();
});

// eslint-disable-next-line jest/expect-expect
it("doesn't crash if no navigator handled the action", () => {
it('logs error if no navigator handled the action', () => {
const TestRouter = MockRouter;

const TestNavigator = (props: any) => {
Expand Down Expand Up @@ -366,5 +365,13 @@ it("doesn't crash if no navigator handled the action", () => {
</NavigationContainer>
);

const spy = jest.spyOn(console, 'error').mockImplementation();

render(element).update(element);

expect(spy.mock.calls[0][0]).toMatch(
"The action 'UNKNOWN' with payload 'undefined' was not handled by any navigator."
);

spy.mockRestore();
});
4 changes: 4 additions & 0 deletions packages/core/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export type NavigationAction = {
* Type of the action (e.g. `NAVIGATE`)
*/
type: string;
/**
* Additional data for the action
*/
payload?: object;
/**
* Key of the route which dispatched this action.
*/
Expand Down
13 changes: 11 additions & 2 deletions packages/core/src/useNavigationHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,22 @@ export default function useNavigationHelpers<
const { performTransaction } = React.useContext(NavigationStateContext);

return React.useMemo(() => {
const dispatch = (action: Action | ((state: State) => Action)) =>
const dispatch = (action: Action | ((state: State) => Action)) => {
performTransaction(() => {
const payload =
typeof action === 'function' ? action(getState()) : action;

onAction(payload);
const handled = onAction(payload);

if (!handled && process.env.NODE_ENV !== 'production') {
console.error(
`The action '${payload.type}' with payload '${JSON.stringify(
payload.payload
)}' was not handled by any navigator.`
);
}
});
};

const actions = {
...router.actionCreators,
Expand Down

0 comments on commit 0252bdc

Please sign in to comment.