Skip to content
This repository has been archived by the owner on Nov 11, 2023. It is now read-only.

Commit

Permalink
Catch network fetch error
Browse files Browse the repository at this point in the history
  • Loading branch information
fabien0102 committed Dec 12, 2018
1 parent c0b6e10 commit a752635
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 23 deletions.
21 changes: 21 additions & 0 deletions src/Get.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,27 @@ describe("Get", () => {
});
});

it("should handle network error", async () => {
nock("https://my-awesome-api.fake")
.get("/")
.replyWithError({ message: "You shall not pass!" });

const children = jest.fn();
children.mockReturnValue(<div />);

render(
<RestfulProvider base="https://my-awesome-api.fake">
<Get path="">{children}</Get>
</RestfulProvider>,
);

await wait(() => expect(children.mock.calls.length).toBe(2));
expect(children.mock.calls[1][0]).toEqual(null);
expect(children.mock.calls[1][1].error).toMatchObject({
message: "Failed to fetch: request to https://my-awesome-api.fake failed, reason: You shall not pass!",
});
});

it("should deal with non standard server error response (nginx style)", async () => {
nock("https://my-awesome-api.fake")
.get("/")
Expand Down
56 changes: 33 additions & 23 deletions src/Get.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,36 +249,46 @@ class ContextlessGet<TData, TError, TQueryParams> extends React.Component<
};

const request = new Request(makeRequestPath(), this.getRequestOptions(thisRequestOptions));
const response = await fetch(request, { signal: this.signal });
const { data, responseError } = await processResponse(response);
try {
const response = await fetch(request, { signal: this.signal });
const { data, responseError } = await processResponse(response);

// avoid state updates when component has been unmounted
if (this.signal.aborted) {
return;
}
// avoid state updates when component has been unmounted
if (this.signal.aborted) {
return;
}

if (!response.ok || responseError) {
const error = {
message: `Failed to fetch: ${response.status} ${response.statusText}${responseError ? " - " + data : ""}`,
data,
};
if (!response.ok || responseError) {
const error = {
message: `Failed to fetch: ${response.status} ${response.statusText}${responseError ? " - " + data : ""}`,
data,
};

this.setState({
loading: false,
error,
});
this.setState({
loading: false,
error,
});

if (!this.props.localErrorOnly && this.props.onError) {
this.props.onError(error, () => this.fetch(requestPath, thisRequestOptions), response);
}
if (!this.props.localErrorOnly && this.props.onError) {
this.props.onError(error, () => this.fetch(requestPath, thisRequestOptions), response);
}

return null;
}
return null;
}

const resolved = await resolveData<TData, TError>({ data, resolve });
const resolved = await resolveData<TData, TError>({ data, resolve });

this.setState({ loading: false, data: resolved.data, error: resolved.error });
return data;
this.setState({ loading: false, data: resolved.data, error: resolved.error });
return data;
} catch (e) {
this.setState({
loading: false,
error: {
message: `Failed to fetch: ${e.message}`,
data: e,
},
});
}
};

public render() {
Expand Down

0 comments on commit a752635

Please sign in to comment.