I have the following fetch() api but the catch blocks aren't working correctly. The error message I get is:
SyntaxError: Unexpected token < in JSON at position 0 undefined
but what I'm expecting is:
something went wrong null
here's the api:
const getBtn = document.getElementById('get-btn')
const postBtn = document.getElementById('post-btn')
const sendHttpRequest = (method, url, data) => {
return fetch(url, {
method: method,
body: JSON.stringify(data),
headers: data ? {'Content-Type': 'application/json'} : {}
})
.then(response => {
console.log(response.status)
if(response.status >= 400 || response == null){
return response.json()
.then(errResData => {
const error = new Error('something went wrong')
error.data = errResData
throw error;
})
}
return response.json()
})
}
const getData = () =>{
sendHttpRequest('GET','http://localhost/async/fetch/data.jsonx')
.then(responseData => {
console.log(responseData)
})
.catch(err =>{
console.log(err,err.data)
})
}
const sendData = () =>{
sendHttpRequest('POST','http://localhost/async/fetch/data.phpx',{
email: 'someemail@gmail.com',
password: 'compas'
})
.then(responseData => {
console.log(responseData)
})
.catch(err => {
console.log(err,err.data)
})
}
getBtn.addEventListener('click',getData)
postBtn.addEventListener('click',sendData)
In order to see if a body is parseable as JSON, you need to call .json
on the Promise. That will return a Promise that either resolves to the parsed value, or will throw due to the body not being parseable.
If it isn't parseable, .then
s connected to it won't run; return response.json().then
will not work if the body isn't parseable, so the interpreter never gets to new Error('something went wrong')
.
.then(response => {
console.log(response.status)
if(response.status >= 400 || response == null){
return response.json()
.then(errResData => {
const error = new Error('something went wrong')
error.data = errResData
throw error;
})
}
return response.json()
should be
.then(response => {
console.log(response.status)
if(response.status >= 400 || response == null){
return response.json()
.catch(errResData => {
const error = new Error('something went wrong')
error.data = errResData
throw error;
})
}
return response.json()
if the non-parseable response will always fulfill the condition response.status >= 400 || response == null
.
The throw error
inside the .catch
in the edited code will result in the Promise rejecting, so getData
's .catch
will see the error.