How to handel "net::ERR_QUIC_PROTOCOL_ERROR 200" in a fetch? - javascript

By simulating a Lie-Fi connection I noticed that I get an (net::ERR_QUIC_PROTOCOL_ERROR) error that didn't triggered the catch part of the fetch statement.
The reason that the fetch wasn't triggered is that the status code of the network request returned 200. Why is this Error OK (200)?.
But the main question is how can I detect and handle these errors?
This question gets more interesting in case the fetch is part of a fetch event handel of a serviceworker. For when the serviceworker tries to fetch something from the internet and if that isn't possible returns a result from the cache. These errors however will not be seen as an error and therefore the data from the cache will not be returned. As a user I then will not get the offline experience I would expect.
// please set Network Throttling to Lie-Fi (1kbit/s up&down)
const timeoutSimulation = () => {
return fetch('https://thispersondoesnotexist.com/image', {mode: 'no-cors'})
.then((response) => {
console.log(`would not expect to see this message, due to the net error`);
return response;
})
.catch((error) => {
console.log('expect this error to be shown', error);
})
}

Related

Why does a GET request with fetch API log a server response error message into the browser console?

I am using the fetch-API to send a GET request to a Spring Boot backend. The request looks somewhat like this:
const response = await fetch(url);
if (response.status === 200) {
// do something
} else {
response.json().then(response => console.log(response));
}
In case that I send a valid request, i.e. the url passed into fetch() is valid, everything works fine. In case that I pass an invalid url into fetch(), however, two things appear to be happenning:
A serer response message is thrown:
My Spring Boot backend return a ResponseEntity with a custom error message as body. This error message is logged inside the else-block of the above code snippet:
While I do expect the second point to be happenning, I cannot explain the first. I don't understand why this server-response error is logged into my browser console. I do have a few catch-blocks inside my code, something like:
const response = await fetch(url).catch(error => console.log(error));
As far as I know, however, fetch only throws an error if a network connection error occurred or similar. A response code not equal to 200 does not result in fetch throwing an error. So, as I said, I don't know where this error message comes from and I was hoping that somebody does, maybe it is something generic to the fetch API that I just don't know?
I recommend using "try catch" to better capture errors.
If the response is positive and it's a json, use a "then" after the fetch.
try {
const response = await fetch(url).then(res => res.json());
// do something
} catch (e) {
console.error(e);
}
If you're getting a 400 error, check the api documentation to see if you're passing the parameter incorrectly. or if that is not the route

node-fetch HTTP Errors not being caught

I am having some problems with catching nodejs fetch exceptions
What I am expecting to happen is:
HTTP error of some sort occurs in my fetch call
CheckResponseStatus function runs and an error an error is thrown with the server error status and text
This error is caught and the ServerError function runs which (just for testing) will just print the error to the console.
However, the error printed to the console is:
Cannot connect to Server. Check you are using the correct IP Address and the server is running.
FetchError: request to http://localhost:3689/api/outputs failed, reason: connect ECONNREFUSED 127.0.0.1:3689
This is implying that the error I have thrown is not being caught, some default fetch error is being caught, and CheckResponseStatus is not being run.
My code is below
Node-Fetch HTTP Request:
async function getStatus(serverip,serverport){
return await fetch(`http://${serverip}:${serverport}/api/outputs`)
.then(this.checkResponseStatus)
.then(res => res.json())
.catch((err) => this.ServerError(err));
}
CheckResponseStatus Function:
checkResponseStatus(res) {
if(res.ok){
return res
}
//will add elseif's here for different HTTP errors
else {
throw new Error(`The HTTP status of the response: ${res.status} (${res.statusText})`);
}
}
ServerError Function:
ServerError(err){
console.log('Cannot connect to Server. Check you are using the correct IP Address and the server is running.');
console.log(err);
}
Thanks for any suggestions or help.
If fetch is unable to connect to the remote server, it will reject. In your code, checkResponseStatus is never called because fetch is never able to get a response; the first two .then blocks are skipped because fetch rejected, so execution goes directly to the .catch block.
If you want network errors to run through checkResponseStatus, you can add a second .catch before the first .then and format the error into a "response":
fetch(`http://${serverip}:${serverport}/api/outputs`)
.catch(err => {
// return a mock failed response for checkResponseStatus to handle
return {
ok: false,
status: -1,
statusText: 'Network Failure',
};
})
.then(this.checkResponseStatus)
.then(res => res.json())
.catch((err) => this.ServerError(err));
However, I believe your code is currently running how I would expect it to - a network failure skips checkResponseStatus, which makes sense because there's no real response to check.

axios.post.then() is ignoring the then() part for some reason

I have this function...
function waterCalibrator() {
axios.post("http://localhost:3001/api/update-water", {
waterValue: props.moisture
}).then(function(response){
console.log("Water calibration worked")
console.log(response);
}).catch(function(error) {
console.log(error);
})
props.airValueObject.setWaterFlag(true);
props.airValueObject.setWaterValue(props.moisture);
}
Can anyone explain why then() is not ever triggered? I have no errors. It simply isn't triggering. Everything works except for this...
}).then(function(response){
console.log("Water calibration worked")
console.log(response);
}).catch(function(error) {
console.log(error);
})
server side looks like this...
app.post("/api/update-water", (req, res) => {
const waterValue = req.body.waterValue;
const sqlUpdateWater = "UPDATE user SET waterValue=? WHERE uid='j' ";
db.query(sqlUpdateWater, [waterValue], (err, result)=>{
console.log(`water is: ${waterValue}`)
})
})
You are getting a 204 status code, which means the request went through successfully but there is no content at all, hence you are trying to log nothing.
The HTTP 204 No Content success status response code indicates that the request has succeeded, but... The common use case is to return 204 as a result of a PUT request, updating a resource, without changing the current content of the page displayed to the user. If the resource is created, 201 Created is returned instead. If the page should be changed to the newly updated page, the 200 should be used instead.
You also need, as suggested in previous comments, open the dev console and check the status of the promise itself. This promise seems to be successful.
If this answer helps solving the issue, consider accepting the answer or upvoting it. Thanks.

Can We Explicitly Catch Puppeteer (Chrome/Chromium) Error net::ERR_ABORTED?

Can we explicitly and specifically catch Puppeteer (Chromme/Chromium) error net::ERR_ABORTED? Or is string matching the only option currently?
page.goto(oneClickAuthPage).catch(e => {
if (e.message.includes('net::ERR_ABORTED')) {}
})
/* "net::ERROR_ABORTED" occurs for sub-resources on a page if we navigate
* away too quickly. I'm specifically awaiting a 302 response for successful
* login and then immediately navigating to the auth-protected page.
*/
await page.waitForResponse(res => res.url() === href && res.status() === 302)
page.goto(originalRequestPage)
Ideally, this would be similar to a potential event we could catch with page.on('requestaborted')
I'd recommend putting your api calls and so in a trycatch block
If it fails, you catch the error, like you are currently doing. But it just looks a bit nicer
try {
await page.goto(PAGE)
} catch(error) {
console.log(error) or console.error(error)
//do specific functionality based on error codes
if(error.status === 300) {
//I don't know what app you are building this in
//But if it's in React, here you could do
//setState to display error messages and so forth
setError('Action aborted')
//if it's in an express app, you can respond with your own data
res.send({error: 'Action aborted'})
}
}
If there are not specific error codes in the error responses for when Puppeteer is aborted, it means that Puppeteer's API has not been coded to return data like that, unfortunately :')
It's not too uncommon to do error messages checks like you are doing in your question. It's, unfortunately, the only way we can do it, since this is what we're given to work with :'P

Angular 2 Http get not triggering

As said in the title, nothing is happening when I subscribe to my observable. There is no error in the console or during the build. Here is my code :
My service
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25').map(
(res: Response) => {
return res.json();
});
}
My component
ngOnInit() {
this.planifRequestService.getBlueCollars().subscribe(
data => {
this.blueCollars = data;
console.log('Inner Blue Collars', this.blueCollars);
},
err => console.log(err)
);
console.log('Value BlueCollars : ', this.blueCollars);
}
So the second console.log is triggering with "Value BlueCollars : Undefined", and the log in my subscribe is never showed. As well, I can't see the request sent in the Networt tab of Chrome.
So I tried to simplify everything with the following code :
let response: any;
this.http.get('myUrl').subscribe(data => response = data);
console.log('TestRep: ', response);
Same problem here, no error, response is undefined. It seems the subscribe is not triggering the observable. (The URL is correct, it is working on my swagger or with postman.)
I'm on Angular 2.4.9
Edit
So I tried to copy/past the code of my request on a brand new project, everything is working fine. The request is triggered and I can get the JSON response correctly. So there is something maybe on the configuration of my project that is forbiding the request to trigger correctly.
Ok just found what was going on. I am using a fake backend in order to try my login connexions that is supposed to catch only specified URL. However for wathever raison it was catching all the requests, so that explain everything. Thx for your help everybody.
Try adding a catch block to your service code:
getBlueCollars(): Observable<BlueCollar[]> {
return this.http.get(this.defaultAPIURL + 'bluecollar?limit=25')
.map(
(res: Response) => {
return res.json();
})
.catch(err => Observable.throw(err))
}
Don't forget to
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';`
I imagine this will result in the error that'll give you an idea where your code is going wrong.
The reason the console.log outside the subscribe call is undefined is because the subscribe/http call is happening asynchronously and so, in effect, the order (in time!) the code is running is:
1) the observable is subscribed to (and then waits for a response)
2) the outer console log runs with blueCollars undefined
3) when the response (or error) comes back from the http request (potentially after several seconds), only then will the inner assignment of this.blueCollar = data happen (and the inner console log), OR an error will get logged
Apart from that the subscribe code looks fine...!

Categories

Resources