Your best bet is to look at the response in your devtools' network tab. That will show you the full response.
But if you want to do it in code, you can separate reading the response from parsing it by using the text method instead of the json method, then parsing the text yourself.
The parsing error may be down to the fact you aren't checking for HTTP success. As I noted on my old anemic blog here, fetch only rejects its promise on network errors, not HTTP errors (like 404, 500, etc.). To check for HTTP success, look at the ok or status properties.
Here's the minimal-changes version separating reading the response from parsing it, and checking for HTTP success before reading it at all:
async function test() { try { let n = await fetch("https://stackoverflow.com") .then((res) => { if (!res.ok) { // *** throw new Error(`HTTP error ${res.status}`); // *** } // *** return res.text(); // *** }) .then((text) => { // *** you can look at `text` here in a debugger, or // *** log it, save it, etc., before parsing below // *** (which might throw an error) try { const data = JSON.parse(text); // *** return data.results.length; } catch (error) { console.error("Parsing error", e); console.error("Text we were parsing:", text); } }) .catch((e) => { console.error("Catch 2", e); }); // ...do something with `n`... } catch (e) { console.error("Catch 3", e); } }
But a couple of things there:
I wouldn't mix async/await with explicit promise callbacks like that.
With that and with your original code, errors will result in n receive the value undefined, because the catch handlers (and my new try/catch block in the then handler) don't return anything.
Instead:
async function test() { try { const res = await fetch("https://stackoverflow.com"); if (!res.ok) { throw new Error(`HTTP error ${res.status}`); } const text = await res.text(); // *** you can look at `text` here in a debugger, or // *** log it, save it, etc., before parsing below // *** (which might throw an error) try { const data = JSON.parse(text); const n = data.results.length; // ...do something with `n`... } catch (error) { console.error("Parsing error", e); console.error("Text we were parsing:", text); } } catch (e) { console.error("Catch 3", e); } }
Or if you want to respond differently to the parsing error, wrap that bit in a try/catch, etc.
.textif you are fetching a source which does not return jsonconst text = await resp.text(); try { return JSON.parse(text); } catch(err) { return text; }to a chain of Promises? What prevents you to have the exact same try catch in your .then callback? It's all sync after .text()