Inconsistent response handling in v2
Consider a request to a server that successfully returns XML data (aka anything that is not JSON).
In the node version we have this flow:
- construct
outas the concatenated data stream string - since the header
content-typedoes not includeapplication/jsonso... - the response
dataproperty is set to theout(aka the response body realized) - the promise is resolved with that response (aka
response.datais the response body XML string)
However, in the fetch version we have this flow:
- the header
content-typedoes not includeapplication/jsonso... - try to parse the string from
fetch.text()as JSON - since the response is XML this throws
- set the error on the response
- the promise is rejected but the
fetch.text()string is not available on the response
Well I may have spent too long staring at code and fried my brain, I see now !~tmp.indexOf('application/json') would be true in my example, so that flow result is incorrect. 🤦
The response is still inconsistent, but in a way that I can handle:
The node version resolves the promise with response.data being the fully realized response body XML string.
Whereas the fetch version simply resolves the promise with response, aka the response body is not yet fully realized.
My resolution to this was, in my code, to simply do:
let response = await httpie(url, options)
const bodyString = typeof response.data === 'string'
? response.data
: await response.text()
I don't know what the "Right Thing" to do here would be, since the goal isn't full strict isomorphism between the two, but since you're waiting for the body stream to be realized in the Node version, it seems like it might be appropriate to do the same in the fetch version? Something like this, probably:
if (!tmp || !~tmp.indexOf('application/json')) {
- reply(rr);
+ rr.text().then(str => {
+ rr.data = str;
+ reply(rr);
+ });
} else {