Cannot catch errors generated by fetch - javascript

In the try-catch syntax, I want to use fetch to catch errors when aborting while waiting.
I get an error in the console even though I describe it as follows
JavaScript
controller = new AbortController();
const signal = controller.signal;
try {
const data = await fetch(url, { signal })
} catch(e) {
return
}
console
Uncaught (in promise) DOMException: The user aborted a request.
The same problem occurred when I used promise chain.

Related

FetchError: request to url failed, reason ECONNREFUSED crashes server despite try catch being in place

The problem
FetchError: request to https://direct.faforever.com/wp-json/wp/v2/posts/?per_page=10&_embed&_fields=content.rendered,categories&categories=638 failed, reason: connect ECONNREFUSED
I'm doing some API calls for a website using fetch. Usually there are no issues, when a request "fails" usually the catch error gets it and my website continues to run. However, when the server that hosts the API calls is down/off, my fetch API calls crash the website entirely (despite being on a try catch loop).
As far as I'm concerned, shouldnt the catch block "catch" the error and continue to the next call? Why does it crash everything?
My wanted solution
For the website to just move on to the next fetch call / just catch the error and try again when the function is called again (rather than crashing the entire website).
The code
Here is an example of my fetch API call (process.env.WP_URL is = https:direct.faforever.com )
async function getTournamentNews() {
try {
let response = await fetch(`${process.env.WP_URL}/wp-json/wp/v2/posts/?per_page=10&_embed&_fields=content.rendered,categories&categories=638`);
let data = await response.json();
//Now we get a js array rather than a js object. Otherwise we can't sort it out.
let dataObjectToArray = Object.values(data);
let sortedData = dataObjectToArray.map(item => ({
content: item.content.rendered,
category: item.categories
}));
let clientNewsData = sortedData.filter(article => article.category[1] !== 284);
return await clientNewsData;
} catch (e) {
console.log(e);
return null;
}
}
Here's the whole code (this whole thing is being called by express.js in line 246 (the extractor file).
Extractor / Fetch API Calls file
https://github.com/FAForever/website/blob/New-Frontend/scripts/extractor.js
Express.js file in line 246
https://github.com/FAForever/website/blob/New-Frontend/express.js#:~:text=//%20Run%20scripts%20initially%20on%20startup

Modern way to consume a json based flask api with javascript

I'm new to web programming, I been learning the basics of Flask such as http requests, template inheritance, flask forms, saving data on the database etc.
I saw that some people only use flask as backend and its api its json based, and for the frontend they use React. Since I'm learning the basics of JavaScipt I don't want to use libraries like React or Jquery, I want to use just JavaScript. I was searcing and found that many people use AJAX with Jquery, or axios to consume an api. Is there any way to consume my flask api with just JavaScript without using any library or framework?
Is there any way to consume my flask api with just JavaScript without using any library or framework?
Yes, using fetch, which is built in to all modern browsers. A query for data transmitted in JSON format looks like this:
In a non-async function, if you are returning the result of the last call to then:
// Do the request
return fetch("/path/to/the/data", {/*...options if any...*/})
.then(response => {
// Check for HTTP success (`fetch` only rejects on *network* failure)
if (!response.ok) {
// HTTP error
throw new Error(`HTTP error ${response.status}`);
}
// Read the body of the response and parse it from JSON into objects and such
return response.json();
})
.then(data => {
// ...`data` has the data from the call, parsed and ready to go
});
...or if you aren't:
// Do the request
return fetch("/path/to/the/data", {/*...options if any...*/})
.then(response => {
// Check for HTTP success (`fetch` only rejects on *network* failure)
if (!response.ok) {
// HTTP error
throw new Error(`HTTP error ${response.status}`);
}
// Read the body of the response and parse it from JSON into objects and such
return response.json();
})
.then(data => {
// ...`data` has the data from the call, parsed and ready to go
})
.catch(error => {
// ...something went wrong, handle/report `error`...
});
fetch uses promises, so you'll want to read up on those.
In an async function, if you are allowing errors to propagate to the caller:
// Do the request
const response = await fetch("/path/to/the/data", {/*...options if any...*/});
// Check for HTTP success (`fetch` only rejects on *network* failure)
if (!response.ok) {
// HTTP error
throw new Error(`HTTP error ${response.status}`);
}
// Read the body of the response and parse it from JSON into objects and such
const data = await response.json();
// ...`data` has the data from the call, parsed and ready to go
or if you aren't:
try {
// Do the request
const response = await fetch("/path/to/the/data", {/*...options if any...*/});
// Check for HTTP success (`fetch` only rejects on *network* failure)
if (!response.ok) {
// HTTP error
throw new Error(`HTTP error ${response.status}`);
}
// Read the body of the response and parse it from JSON into objects and such
const data = await response.json();
// ...`data` has the data from the call, parsed and ready to go
} catch (error) {
// ...something went wrong, handle/report `error`...
}
More about async functions on MDN.

How to handle 404 error in a async/await?

When fetching postcode from Postcode io API, I tried this error handling code:
async getCoord() {
const postcodeAPI = `http://api.postcodes.io/postcodes/dt12pbbbbbbbbb`;
let response;
try {
response = await fetch(postcodeAPI);
}
catch (e) {
console.log(e);
};
};
The fetch method returns a 404 error as postcode is invalid. In my understanding the try block should be tried and skipped and the error should be caught by the catch method, but instead I got this red 404 error in console:
which happens in the try block, and is the same as no error handling in the code. Why does this happen? Is it because this is browser default behaviour? Is there a way to improve the error handling here?
EDIT
What I wanted was the red console error to disappear and show my own error information instead, but the console error seems unavoidable.
Fetch API doesn't throw errors on any status code. It only throws errors on network failures, i.e. when it couldn't finish the request itself.
You can use response.ok to check if the request finished with 2XX status code.
async getCoord() {
const postcodeAPI = `http://api.postcodes.io/postcodes/dt12pbbbbbbbbb`;
let response;
try {
response = await fetch(postcodeAPI);
if (!response.ok) throw new Error('Request failed.');
}
catch (e) {
console.log(e);
};
};
You can also explicitly check the status code if you need:
if (response.status === 404) {
// handle 404
}
As for your question about logging 404 errors in the console, there's no way or need to avoid it. Whenever you make a request, it's being logged in the dev tools. But dev tools are just what they are called - tools for devs. You can safely assume your users won't look there and even if someone does, having 404 there is not the end of the world.

Unhandled promise rejection stripe paymentIntent example

I'm trying to setup a stripe payment app using node and express, following the example here:
https://stripe.com/docs/payments/accept-a-payment#web
I created the route in my server side app code as indicated, and inserted the client-side code in my html file. I'm trying to create the app without a template engine, just html/css/javascript/node.
var response = fetch('/secret').then(function(response) {
return response.json();
}).then(function(responseJson) {
var clientSecret = responseJson.client_secret;
// Call stripe.confirmCardPayment() with the client secret.
});
I'm getting the following error:
Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
I'm new to promises and not sure what the syntax with this code should be. Can I add
promise1.catch((error) => {
console.error(error);
});
Yes, adding a catch method at the end would catch the error(rejected Promise). What you suggested would work.
var response = fetch('/secret').then(function(response) {
return response.json();
}).then(function(responseJson) {
var clientSecret = responseJson.client_secret;
// Call stripe.confirmCardPayment() with the client secret.
}).catch(function(err) {
// Handle error
});

Error bubbles to console even though it is handled

I am using isomorphic-fetch to perform AJAX requests from my react-redux application. In my api middleware I have the following function which calls the external resource:
import fetch from 'isomorphic-fetch';
function callApi({ endpoint, method, body, params = {} }) {
let route = generateRoute(endpoint, params);
return fetch(route, generateFetchOptions(method, body))
.then(response => {
if (!response.ok) {
return Promise.reject(response);
}
return response.json();
});
}
The above function is called by the following piece of code:
return callApi(callAPI).then(
response => next(actionWith({
response,
type: successType,
statusCode: 200
})),
error => error.json().then(errorObject => {
return next(actionWith({
type: failureType,
statusCode: errorObject.statusCode,
error: errorObject.message || 'Something bad happened'
}));
})
);
If I reject with Promise.reject(response) the error is being handled by the error handler, but for some reason the error also bubbles to the browser console (in my case Chrome).
Here is a screenshot from the console which shows what is happening (api.js:34 is the second line of the callApi method):
This is the usual behavior (in probably every browser?) when hitting an error during an HTTP request (no matter whether a linked image cannot be found, or an XHR fails). No matter if and how you handle those errors, they will always be logged to the console. There is no way to suppress this behavior.
References:
Provide a way not to display 404 XHR errors in console
How can I stop jQuery.ajax() from logging failures to the console?

Categories