add error handling for fetching users

This commit is contained in:
Maren Süwer
2018-07-19 11:57:59 +02:00
parent 9593a18a55
commit 8562b9d65e
3 changed files with 43 additions and 17 deletions

View File

@@ -43,7 +43,14 @@ class Users extends React.Component<Props, User> {
<UserTable entries={userEntries} deleteUser={deleteUser} /> <UserTable entries={userEntries} deleteUser={deleteUser} />
</div> </div>
); );
} else { } else if(error){
return (
<div>
<ErrorNotification error={error} />
</div>
);
}
else {
return <Loading />; return <Loading />;
} }
} }

View File

@@ -46,11 +46,13 @@ function requestUsers() {
}; };
} }
function failedToFetchUsers(url: string, err: Error) { export function failedToFetchUsers(url: string, error: Error) {
return { return {
type: FETCH_USERS_FAILURE, type: FETCH_USERS_FAILURE,
payload: err, payload: {
url error,
url
}
}; };
} }
@@ -77,12 +79,9 @@ export function fetchUsers() {
.then(data => { .then(data => {
dispatch(fetchUsersSuccess(data)); dispatch(fetchUsersSuccess(data));
}) })
.catch(err => { .catch(cause => {
if (err === NOT_FOUND_ERROR) { const error = new Error(`could not fetch users: ${cause.message}`);
dispatch(usersNotFound(USERS_URL)); dispatch(failedToFetchUsers(USERS_URL, error));
} else {
dispatch(failedToFetchUsers(USERS_URL, err));
}
}); });
}; };
} }
@@ -120,12 +119,9 @@ export function fetchUser(name: string) {
.then(data => { .then(data => {
dispatch(fetchUserSuccess(data)); dispatch(fetchUserSuccess(data));
}) })
.catch(err => { .catch(cause => {
if (err === NOT_FOUND_ERROR) { const error = new Error(`could not fetch user: ${cause.message}`);
dispatch(usersNotFound(userUrl)); dispatch(failedToFetchUsers(USERS_URL, error));
} else {
dispatch(failedToFetchUsers(userUrl, err));
}
}); });
}; };
} }
@@ -386,6 +382,14 @@ export default function reducer(state: any = {}, action: any = {}) {
usersByNames: newUserByNames usersByNames: newUserByNames
} }
case FETCH_USERS_FAILURE: case FETCH_USERS_FAILURE:
return {
...state,
users: {
...state.users,
loading: false,
error: action.payload.error
}
};
case DELETE_USER_FAILURE: case DELETE_USER_FAILURE:
const newState = reduceUsersByNames(state, action.payload.user.name, { const newState = reduceUsersByNames(state, action.payload.user.name, {
loading: false, loading: false,

View File

@@ -24,7 +24,8 @@ import {
DELETE_USER_FAILURE, DELETE_USER_FAILURE,
deleteUser, deleteUser,
updateUserFailure, updateUserFailure,
deleteUserSuccess deleteUserSuccess,
failedToFetchUsers
} from "./users"; } from "./users";
import reducer from "./users"; import reducer from "./users";
@@ -442,6 +443,20 @@ describe("users reducer", () => {
expect(newState.users.error).toBe(null); expect(newState.users.error).toBe(null);
}); });
it("should set error state if users could not be fetched", () => {
const state = {
users: {
error: null,
loading: true
}
};
const error = new Error("could not edit user zaphod: ..");
const newState = reducer(state, failedToFetchUsers('/users', error));
expect(newState.users.error).toBe(error);
expect(newState.users.loading).toBeFalsy();
});
it("should not replace whole usersByNames map when fetching users", () => { it("should not replace whole usersByNames map when fetching users", () => {
const oldState = { const oldState = {
usersByNames: { usersByNames: {