I'm fetching data from an API in that way, and i trying to catch an 404 error on it if the user search for a invalid city but is not working.
const search = evt => {
if (evt.key === "Enter") {
fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
.then(res => res.json())
.then(result => {
setWeather(result);
setQuery('');
}).catch(() => console.log("error"));
}
}
console
See the documentation: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.
You have to use the response parameter provided by .then(response => {...}) and check response.ok or response.status to get an 404 (or 500) error.
Your code works well, as you can see:
const search = evt => {
if (evt.key === "Enter") {
fetch('http://dfsdfsdfdsfsdfdfs.com')
.then(res => res.json())
.catch(() => console.log("error"));
}
}
search({key : 'Enter'});
But an error code from the server is not considered as an error with fetch so you have to parse the response yourself and react accordingly.
You can use res.ok that will return true if the status code is in the 200-299 range. For more information you can check the Response object documentation
As mentioned the docs, since fetch doesn't do a catch on 404 or 500 status, you can mimic the behavior by throwing an error and catching in the catch section.
fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
.then((response) => {
if(response.status == 404){
throw '404 page not found';
}
return response.json();
})
.then((response) => {
console.log('your JSON string ',response);
})
.catch((err) => {
console.error(err);
});
I was able to get the error that way:
const search = evt => {
if (evt.key === "Enter") {
fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
.then(res => res.json())
.then(result => {
setWeather(result);
setQuery('');
}).then((data) => {
if (data === undefined) {
alert("City not found");
}
});
}
}
Related
I have got the response from the JSON API, but I don't know how to parse it, it just comes back with an error, I don't know enough about it to figure it out, it returns:
(node:36308) UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token o in JSON at position 1
var fetch = require('node-fetch');
fetch('https://sv443.net/jokeapi/v2/joke/Any', function(res){
if (res.ok) {
return res;
} else {
console.log(res.statusText);
}
})
.then(res => res.json())
.then((json) => {
var parsedData = JSON.parse(json)
console.log(parsedData.joke);
});
You just need to do the following to access the delivery.
fetch("https://sv443.net/jokeapi/v2/joke/Any?type=single")
.then(response => {
return response.json();
})
.then(json => {
// likely to be json.delivery but cannot
// confirm until rate limits have been lifted
console.log(JSON.stringify(json));
})
.catch(err => {
console.log(err);
});
Try this:
fetch('https://sv443.net/jokeapi/v2/joke/Any', function(res){
if (res.ok) {
return res;
} else {
console.log(res.statusText);
}
})
.then(response => response.json())
.then(data => console.log(data));
You are already parsing it with res.json(). It returns an object (in promise) which can be accessed directly. Depending on a type prop you may have different props to check for. For example twopart joke will have setup: question, and delivery: answer
i try to throw error message but it throw me this message : (use React and NodeJS)
return SyntaxError: Unexpected token U in JSON at position 0
fetch("http://localhost:3000/api/register", options)
.then(response => response.json())
.then(user => {
alert('Registration successful !')
this.props.history.push("/");
})
.catch(err => {
console.error(err)
console.log(err.message)
});
}
server side :
router.post('/', async (request, response) => {
try {
const user = request.body;
const newUser = await registerLogic.addUser(user);
if (newUser === 0) {
throw "User name already exists";
}
if(newUser === 1){
throw "Something is missing";
}
response.status(201).json(newUser);
} catch (error) {
console.log(error);
response.status(500).send(error);
}
});
The error Unexpected token U in JSON at position 0 tells you pretty much what's going on here: the first character of the JSON you’re trying to parse is literally a “U”.
Looking at your server-side code, you’re throwing an error “User name already exists”, catching that error, and then returning that message as the response body. Unfortunately, it's not valid JSON, hence the error.
Instead try returning a valid JSON response by updating your catch statement like this:
try {
// ...
} catch (error) {
response
.status(500)
.send(JSON.stringify({ error }));
}
Your response is not json, in your catch block return json response.
} catch (error) {
console.log(error);
response.status(500);
response.json({ message: error.message })
}
In your fetch, check status code returned from the backend.
fetch("http://localhost:3000/api/register", options)
.then(response => response.json())
.then(user => {
if (user.status !== 200) {
alert('ERR', user);
return;
}
alert('Registration successful !')
this.props.history.push("/");
})
.catch(err => {
console.error(err)
console.log(err.message)
});
}
The other answers deal with your original issue well. To answer your followup questions
when i do it now it not get the catch and contine to .then and send me success message
Fetch will not reject the promise for failed HTTP status codes. This may be a surprise compared to Angular or jQuery which will. Fetch will only reject the promise for network level errors, connection dropped out etc.
This is stated in the docs
What you can do instead is something like this:
fetch("http://localhost:3000/api/register", options)
.then(async response => {
if (!response.ok)
throw new Error(await response.text());
return response;
})
.then(response => response.json())
.then(user => {
alert('Registration successful !')
this.props.history.push("/");
})
.catch(err => {
console.error(err)
console.log(err.message)
});
It will check for a successful HTTP status code and reject the promise chain with the server response if it was not. You may want to create your own exception extending the Error class rather than throwing it directly.
I have this fetch function in my service worker and i try to respond with a different image when the pwa is offline. The fetch function inside the catch throws: Uncaught (in promise) TypeError: Failed to fetch.
self.addEventListener('fetch', (e) => {
if (e.request.method === 'GET') {
e.respondWith(
caches.match(e.request).then((cachedResponse) => {
return cachedResponse || fetch(e.request.url)
.then((res) => {
return res;
}).catch(() => {
//if it is a image then
let url1 = e.request.url.replace(".jpg", "_mini.jpg");
return fetch(url1);
/* Or like this
caches.match(url1).then((cResp) => {
return cResp;
})
*/
})
})
)
}
});
Is it not possible to catch an error when you are offline and respond with a "mini" alternativ image or what do i do wrong?
You are returning cachedResponse if it exists, that prevents your replacement logic from being reached. Try to remove cachedResponse ||.
This can be removed as well:
.then((res) => {
return res;
})
Also, if you're offline the return fetch(url1); won't work because the fetch from a Service Worker won't trigger another FetchEvent recursively. So you have to return caches.match(url1) instead, implying it has been cached before.
In the code below, I don't get the response and get an undefined error instead.
fetchData() {
fetch(Global.user_list)
.then((response) => {
if (response.ok) {
return response.json()
}
})
.then((data) => {})
.catch((err)=> {
alert(err)
})
}
I got the same exception by chance. I was doing a refactoring and failed to provide a valid url to the fetch function.
So I would recommend you check what is inside Global.user_list .
I'm making a script to fetch some data from my api:
const success = (response) => {
console.log(response);
};
const failed = (error) => {
console.log(error);
};
axios.$http.get('/somedata')
.then((response) => {
success(response.data);
})
.catch((error) => {
failed(error);
});
/somepage is a non-existing page so it returns a 404. But the catch is not handling this. Why not? In my console I have the error TypeError: Cannot read property 'data' of undefined. Why does it not run the failed() function? I don't understand.
Found out it was related to a custom interceptor handling 401-errors (but not 404 errors)...
Judging by the error message, it looks like "success(response.data);" is being called. Is it possible the server is successfully returning a page that says something like "Error 404" rather than actually returning http response code 404?
You could impliment a check for 404s.
axios.$http.get('/somedata')
.then(response => {
if(response.status !== 404) //or any status code really
success(response.data);
else
failed(response)
})
.catch((error) => {
failed(error);
});
Then again what you probably want to check for is to make sure it's a 200 that returns.
axios.$http.get('/somedata')
.then(response => {
if(response.status === 200)
success(response.data);
else
failed(response)
})
.catch((error) => {
failed(error);
});