I unfortunately am calling a service which may or may not return JSON (or any) body data.
When I do the following, I get the TypeError: body used already for error:
let data = null
try {
data = await res.json()
} catch (e) {
data = await res.text()
}
Two things:
.json() / .text() multiple times.text()you should look into .clone() and be aware of highWaterMark (#386)
(the underlying data is created using stream, which means you can only call json and text once, unless you clone it.)
the alternetive is that you only use .text() and then try to parse the json into a object using JSON.parse(text)
Maybe also worth having a look at some of the headers you get back. eg content-length, content-type that match application/json look also if res.ok is true or false before you continue down the path
Thanks, that's a reasonable solution
I wanted to update on this issue - this has bitten us a few times already that we've noted this issue in our code base as to why we do it this way.
There's also a longer discussion about it on:
https://www.reddit.com/r/javascript/comments/a3g9bi/you_may_not_need_axios/eb606rd/
It's not node-fetch's fault here - the fetch spec dictates that a stream is used as the underlying implementation.
The use-case from the beginning of the post is, imho, very normal and should be supported. I have just tried doing literally the same thing, and I believe many people think the same (probably because we are used to that try { JSON.parse } catch {} paradigm. It is not relevant to consumers of the library that there is some underlying stream etc. as implementation. This should work, all I'm saying...
Most helpful comment
the alternetive is that you only use
.text()and then try to parse the json into a object usingJSON.parse(text)Maybe also worth having a look at some of the headers you get back. eg
content-length,content-typethat matchapplication/jsonlook also ifres.okis true or false before you continue down the path