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

Improve the error layer #30

Merged
merged 6 commits into from
Aug 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/Get.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,30 @@ describe("Get", () => {
message: "Failed to fetch: 401 Unauthorized",
});
});

it("should deal with non standard server error response (nginx style)", async () => {
nock("https://my-awesome-api.fake")
.get("/")
.reply(200, "<html>404 - this is not a json!</html>", { "content-type": "application/json" });

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).toEqual({
data:
"invalid json response body at https://my-awesome-api.fake reason: Unexpected token < in JSON at position 0",
message:
"Failed to fetch: 200 OK - invalid json response body at https://my-awesome-api.fake reason: Unexpected token < in JSON at position 0",
});
});
});

describe("with custom resolver", () => {
Expand Down
11 changes: 7 additions & 4 deletions src/Get.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type ResolveFunction<T> = (data: any) => T;

export interface GetDataError<TError> {
message: string;
data: TError;
data: TError | string;
}

/**
Expand Down Expand Up @@ -171,12 +171,15 @@ class ContextlessGet<TData, TError> extends React.Component<

const request = new Request(`${base}${requestPath || path || ""}`, this.getRequestOptions(thisRequestOptions));
const response = await fetch(request);
const data = await processResponse(response);
const { data, responseError } = await processResponse(response);

if (!response.ok) {
if (!response.ok || responseError) {
this.setState({
loading: false,
error: { message: `Failed to fetch: ${response.status} ${response.statusText}`, data },
error: {
message: `Failed to fetch: ${response.status} ${response.statusText}${responseError ? " - " + data : ""}`,
data,
},
});
return null;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Poll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ class ContextlessPoll<TData, TError> extends React.Component<
});

const response = await fetch(request);
const data = await processResponse(response);
const { data, responseError } = await processResponse(response);

if (!this.isResponseOk(response)) {
const error = { message: `${response.status} ${response.statusText}`, data };
if (!this.isResponseOk(response) || responseError) {
const error = { message: `${response.status} ${response.statusText}${responseError ? " - " + data : ""}`, data };
this.setState({ loading: false, lastResponse: response, data, error });
throw new Error(`Failed to Poll: ${error}`);
}
Expand Down
19 changes: 16 additions & 3 deletions src/util/processResponse.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
export const processResponse = (response: Response) => {
export const processResponse = async (response: Response) => {
if ((response.headers.get("content-type") || "").includes("application/json")) {
return response.json();
try {
return {
data: await response.json(),
responseError: false,
};
} catch (e) {
return {
data: e.message,
responseError: true,
};
}
} else {
return response.text();
return {
data: await response.text(),
responseError: false,
};
}
};