-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: umi.downloader.downloadJson
can return a string if content-type
is not set on response
#89
base: main
Are you sure you want to change the base?
Conversation
|
Hmm what if the response is an actual JSON string though? Like the original body was We initially requested an I don't think there's much we can do about this tbh if we want to maintain the integrity of valid JSON responses. |
That's a fair point.
If the user explicitly requests fetching the data as a json I think we should try to parse it as such, if that's not possible at least print a warning and ideally throw an error, but for backward compatibility we can return a string. |
Isn't that going to be the same issue just somewhere else? Unless I'm misunderstanding what you're suggesting. 😄 |
Ideally we would modify diff --git a/packages/umi-downloader-http/src/createHttpDownloader.ts b/packages/umi-downloader-http/src/createHttpDownloader.ts
index d007c71..5e88bcf 100644
--- a/packages/umi-downloader-http/src/createHttpDownloader.ts
+++ b/packages/umi-downloader-http/src/createHttpDownloader.ts
@@ -34,8 +34,8 @@ export function createHttpDownloader(
request().get(uri).withAbortSignal(options.signal)
);
- let json = response.data;
- if (typeof json === 'string')
+ let json = response.json;
+ if (!response.json && response.body)
try {
json = JSON.parse(response.body);
} catch {
diff --git a/packages/umi-http-fetch/src/createFetchHttp.ts b/packages/umi-http-fetch/src/createFetchHttp.ts
index cb5ecb5..26b7a98 100644
--- a/packages/umi-http-fetch/src/createFetchHttp.ts
+++ b/packages/umi-http-fetch/src/createFetchHttp.ts
@@ -53,6 +53,7 @@ export function createFetchHttp(): HttpInterface {
return {
data: bodyAsJson ?? bodyAsText,
body: bodyAsText,
+ json: bodyAsJson,
ok: response.ok,
status: response.status,
statusText: response.statusText,
Or, we can do the same check in diff --git a/packages/umi-downloader-http/src/createHttpDownloader.ts b/packages/umi-downloader-http/src/createHttpDownloader.ts
index d007c71..3105074 100644
--- a/packages/umi-downloader-http/src/createHttpDownloader.ts
+++ b/packages/umi-downloader-http/src/createHttpDownloader.ts
@@ -35,7 +35,7 @@ export function createHttpDownloader(
);
let json = response.data;
- if (typeof json === 'string')
+ if (!response.headers.get('content-type')?.includes('application/json'))
try {
json = JSON.parse(response.body);
} catch { |
The first solution is not ideal because it will try to unnecessarily parse the response as JSON on every request. The second solution is interesting though. Because we know we are requesting JSON, if the response was not flagged as a JSON response, we know it wasn't parsed and we're going around the double parsing issue. I'd be happy to merge a PR for this second solution. |
Hmm both should be identical I think? |
Hi @lorisleiva , just a gentle reminder to look into this. |
Hey, sorry your previous comment confused me. IMO, the second solution should work and the conditions should not be identical but opposite. I've applied the patches accordingly. Let me know what you think and maybe create a new PR with the final solution? |
Sorry what I meant is both sets of changes should function identically in respect to json parsing. Ideally, we would return a separate json field that would only be populated if the response had a diff --git a/packages/umi/src/HttpResponse.ts b/packages/umi/src/HttpResponse.ts
index b5ae1ff..073e9b3 100644
--- a/packages/umi/src/HttpResponse.ts
+++ b/packages/umi/src/HttpResponse.ts
@@ -7,6 +7,7 @@ import type { HttpResponseHeaders } from './HttpHeaders';
export type HttpResponse<D = any> = {
data: D;
body: string;
+ json?: D;
ok: boolean;
status: number;
statusText: string; If that is acceptable, then it avoids duplicating the header check in the If we cannot modify the Either way, both solutions should have no extra overhead with respect to json parsing. I hope that makes sense, please let me know if you have any questions. |
The
downloadJson()
function should try to parse the response as json even if thecontent-type
header is missing or notapplication/json
.Some providers like
nftstorage.link
do not set thecontent-type
header for some reason, resulting in the response being a string.This PR makes
downloadJson()
try to parse the response as a json instead of silently returning a string.