How do I identify cause of Axios "Network Error"? - reactjs

I can't get an Axios "get" request working for a front-end/back-end pair after moving the code from CentOS 7 to a CentOS 8 instance. The code in question works just fine on a different AWS EC2 instance. I can't make it work on the new EC2 instance running Rocky Linux v8.5.
When I catch the exception to look at the error, I see a most unhelpful:
Error: Network Error
I can find NO information about the complaint was or how to fix it. I can't get ANY useful information about what is causing the issue. I'm sure it's something stupid and easy to fix -- it would be much easier if I can somehow get the technology stack to tell me what the issue is.
I use the axios component to access a Node Express service running on the same instance that hosts the React app. The service is listening to https on port 7003. The React app calls this server, and returns data provided by the service.
I use axios for all communication between the React app and the rest of the world, so I need to fix this.
I use VisualStudio Code (VSC) to develop my React and NodeJS code.
When I exercise the service using wget, it seems to work:
$ wget "https://my.domain.name.com:7003/getEnvironment"
--2022-02-24 21:46:46-- https://my.domain.name.com:7003/getEnvironment
Resolving my.domain.name.com (my.domain.name.com)... 172.30.2.147
Connecting to my.domain.name.com (my.domain.name.com)|172.30.2.147|:7003... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11205 (11K) [application/json]
Saving to: ‘getEnvironment’
getEnvironment 100%[===================================>] 10.94K --.-KB/s in 0s
2022-02-24 21:46:46 (220 MB/s) - ‘getEnvironment’ saved [11205/11205]
I notice that wget says it's using "HTTP" even though I've given it "https" in the command-line.
I run the front-end in VSC using the React/VSC development server. That server listens on port 3003.
I've turned on cors for the service, and it is listening on port 7003 as expected. That's why the wget works.
The back-end (service) code looks something like this:
...
var cors = require('cors');
...
var app = express();
...
app.use(cors({origin: true, credentials: true}));
...
The front-end code that is failing looks like this:
checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response.data;
} else {
const error = new Error(`HTTP Error ${response.statusText}`);
error.status = response.statusText;
error.response = response;
console.log(error);
throw error;
}
}
privateLoadEnvironmentUsingURL(url) {
return axios
.get(url)
.then((response) => {return this.checkStatus(response)})
.catch((error) => {
console.log(error);
throw error;
});
}
I've exercised this with both front-end and service in VSC. The axios call is failing and so far as I can tell is doing so before ever invoking the service.
It takes awhile to fail, leading me to suspect a timeout is in play. I see no indication in the nodejs service code that the request is actually hitting the service.
It therefore appears that the "preflight" negotiation is blocking this call. Turning on cors is pretty much all I know how to do -- I don't have deep insight into cors.
I've been waving voodoo chickens at this code all afternoon to no avail.
How do other developers discover how to fix problems like this when the technology stack presents so little information about what is actually happening?
How do I get this working?

I found and solved the problem, a network configuration issue completely outside axios/nodejs/react. The fact remains that I think it should somehow be possible for a developer to get at least a hint from the exception raised by axios.
For those who are interested, the problem turned out to be the AWS Security Group configuration for the new system. I had to open port 7003 in the Security Group, allowing access from my local IP address, in order for the request to be forwarded to the platform.
I suppose I should have thought of this sooner -- VSC spawns a special Chrome browser on my local system with its own private tunnel and such. It appears that that browser instance running on my local machine makes the request against port 7003. The AWS Security Group was blocking that port, and so the request never made it to the server.
I identified the issue by doing the wget from my local machine rather than from the new target EC2 instance. That failed, and then I attempted to connect with telnet. When the latter could not connect, I knew it was a Security Group issue.
The bottom line is that it is sometimes too easy to forget that ALL React code runs in the browser. I know that's obvious. but its implications sometimes are not.

Related

can't get the back end data when I run a react app from other device

I have a project with react on the front and django/python and postgres on the back
Everything goes ok on the computer, but if I run it from another device, in the same network, the data can’t be loaded, it says axios network error
I found my Ip with ipconfig, suppose it's 192.xxx.xxx.xxx, then I set in the mobile device http:// 192.xxx.xxx.xxx:3000, it runs the application but the data can't be found there, it says AxiosError: Network Error
My computer recognizes the wifi network 2.4, then I connect the phone to the 2.4 network
In the axios call, I set the address as:
const response = await axios.get(
`http://127.0.0.1:8000/api/v1/whole_menu/${restaurantId}`
);
(I’m not using localhost)
But I still get the network error in the phone, but in the computer, everything is ok
What could it be?
Thanks in advance
Rafael
EDIT:
I realise that the calls don't reach the backend, axios rejects the device with the network error
If I follow the react ouput, it doesn't work either
Local: http://localhost:3000
On Your Network: http://192.xxx.xxx.xxx:3000
In the django server, in settings.py, I have:
CORS_ORIGIN_WHITELIST = ("http://127.0.0.1:3000",)
if I set:
CORS_ORIGIN_ALLOW_ALL = True
I get the same error
You probably didn't update your firewall. For other devices to be able to communicate with you pc you have to what's called open your port for tcp traffic, in this case port 3000. You can find how to do so for example here: https://answers.microsoft.com/en-us/windows/forum/all/how-to-open-port-in-windows-10-firewall/f38f67c8-23e8-459d-9552-c1b94cca579a
Be aware that others on your network can now send traffic to your laptop. Therefor it is wise to revert this when you are done testing.

Network request failed from fetch in reactjs app

I am using fetch in a NodeJS application. Technically, I have a ReactJS front-end calling the NodeJS backend (as a proxy), and then the proxy calls out to backend services on a different domain.
However, from logging errors from consumers (I haven't been able to reproduce this issue myself) I see that a lot of these proxy calls (using fetch) throw an error that just says Network Request Failed, which is of no help. Some context:
This only occurs on a subset of all total calls (lets say 5% of traffic)
Users that encounter this error can often make the same call again some time later (next couple minutes/hours/days) and it will go through
From Application Insights, I can see no correlation between browsers, locations, etc
Calls often return fast, like < 100 ms
All calls are HTTPS, non are HTTP
We have a fetch polyfill from fetch-ponyfill that will take over if fetch is not available (Internet Explorer). I did test this package itself and the calls went through fine. I also mentioned that this error does occur on browsers that do support fetch, so I don't think this is the error.
Fetch settings for all requests
Method is set per request, but I've seen it fail on different types (GET, POST, etc)
Mode is set to 'same-origin'. I thought this was odd, since we were sending a request from one domain to another, but I tried to set it differently and it didn't affect anything. Also, why would some requests work for some, but not for others?
Body is set per request, based on the data being sent.
Headers is usually just Accept and Content-Type, both set to JSON.
I have tried researching this topic before, but most posts I found referenced React native applications running on iOS, where you have to set some security permissions in the plist file to allow HTTP requests or something to do with transport security.
I have implement logging specific points for the data in Application Insights, and I can see that fetch() was called, but then() was never reached; it went straight to the .catch(). So it's not even reaching code that parses the request, because apparently no request came back (we then parse the JSON response and call other functions, but like I said, it doesn't even reach this point).
Which is also odd, since the request never comes back, but it fails (often) within 100 ms.
My suspicions:
Some consumers have some sort of add-on for there browser that is messing with the request. Although, I run with uBlock Origin and HTTPS Everywhere and I have not seen this error. I'm not sure what else could be modifying requests that would cause it to immediately fail.
The call goes through, which then reaches an Azure Application Gateway, which might fail for some reason (too many connected clients, not enough ports, etc) and returns a response that immediately fails the fetch call without running the .then() on the response.
For #2, I remember I had traced a network call that failed and returned Network Request Failed: Made it through the proxy -> made it through the Application Gateway -> hit the backend services -> backend services sent a response. I am currently requesting access to backend service logs in order to verify this on some more recent calls (last time I did this, I did it through a screenshare with a backend developer), and hopefully clear up the path back to the client (the ReactJS application). I do remember though that it made it to the backend services successfully.
So I'm honestly not sure what's going on here. Does anyone have any insight?
Based on your excellent description and detective work, it's clear that the problem is between your Node app and the other domain. The other domain is throwing an error and your proxy has no choice but to say that there's an error on the server. That's why it's always throwing a 500-series error, the Network Request Failed error that you're seeing.
It's an intermittent problem, so the error is inconsistent. It's a waste of your time to continue to look at the browser because the problem will have been created beyond that, either in your proxy translating that request or on the remote server. You have to find that error.
Here's what I'd do...
Implement brute-force logging in your Node app. You can use Bunyan, or Winston or just require(fs) and write out to some file when an error occurs. Then look at the results. Only log it out when the response code from the other server is in the 400 or 500 ranges. Log the request object and the response object.
Something like this with Bunyan:
fetch(urlToRemoteServer)
.then(res => res.json())
.then(res => whateverElseYoureDoing(res))
.catch(err => {
// Get the request & response to the remote server
log.info({request: req, response: res, err: err});
});
where the res in this case is the response we just got from the other domain and req is our request to them.
The logs on your Azure server will then have the entire request and response. From this you can find commonalities. and (🤞) the cause of the problem.

ERR_HTTP2_PROTOCOL_ERROR after authentication is done

I'm trying to use ITfoxtec.Identity.Saml2.MvcCore on a .NET Core 3.1 web application using an in-house IdP.
It works great on our test server (Windows Server 2012, hosted in the IIS) but I can't get it to work on any other server.
This is what happens:
The initial call to the website is correctly identified as a non authenticated call and the user is being sent to the IdP where the user logs in as usual. The SAML-token is then posted back to the web applications assertion consumer service where everything seems like it does what its supposed to, saml2AuthnResponse.Status has statuscode Saml2StatusCodes.Success and the logfile says "AuthenticationScheme: saml2 signed in". Then it reads the ReturnUrl-parameter and log something like "Executing RedirectResult" but then it just stops. Nothing in the logfile, nothing in the IIS-logs. The user is met by the message
This site can’t be reached
...
ERR_HTTP2_PROTOCOL_ERROR
In short, every controller that has the [Authorize]-attribute gives the ERR_HTTP2_PROTOCOL_ERROR-error. When I remove all [Authorize]-attributes the application works great, although without authentication.
I've also tried the example TestWebAppCore-application from ITfoxtec.Identity.Saml2's github-page and it gives the same error. It works on our 2012 test-server but nowhere else.
Any ideas that I can try?
I think you need to trace the calls to see the actual http request and responses send between the browser and server. I usually use Fiddler for tracing the requests/response. Remember to enable Fiddler for https tracing.
My first thought is that the problem can have something to do with cookies. But it is only a guess...
You might be on to something, we disabled http/2 on the server and was greeted instead by this message:
Bad Request - Request Too Long
HTTP Error 400. The size of the request headers is too long.
It uses 5 cookie-chunks for the SAML-data for a total of 19941 bytes which is a bit to much. I've tried to make the application save the sessiondata in classic session objects instead but I cant seem to get it to work.
This is what I added to StartUp.cs:
In ConfigureService:
services.AddMvc()
.AddSessionStateTempDataProvider();
services.AddSession(options =>
options.Cookie.IsEssential = true
);
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
In Configure:
app.UseSession();
But it still fills up the header with cookies. What am I doing wrong? Is there a another way to make the session cookies smaller?

Why is my POST request not reaching my Sails server in a Docker virtual machine?

We have a full-stack app running with a React front-end UI and a Node-based Sails API and Postgres database on the backend. The backend is set to run on a Docker virtual machine. So here's the problem: the UI is up and running fine as is the Docker server and VM as far as we can tell. However, our user login functionality has stopped connecting with our server for some reason. The POST request that is supposed to create a user returns a 404 Not Found error, never actually hitting the /users/create endpoint as it should.
We have tried completely reinstalling docker and the virtual machine, clearing out the cache and starting from scratch. The error does not change. We have also compared the code of the machines that are receiving this error with a computer that is NOT receiving the error and there is no difference in the actual server, endpoint or docker files.
Potentially worth mentioning is that our Sails server in Docker is not able to find and run our grunt file, which it used to be doing (and is still on one computer). But that file isn't doing anything directly related to the server and shouldn't be causing the 404 we don't think so it's probably not relevant.
Another problem is that prior to installing a CORS Chrome Extension that allows same origin requests, we were just getting a CORS error that prevented the request from even going off. The extension seems to have fixed this for now and this is likely also not related, but maybe worth mentioning anyways.
This is our create user JavaScript (React) function in our user reducer.
export const registrationEpic = action$ =>
action$.ofType(USER_REGISTRATION)
.mergeMap(action => ajax.post(`${process.env.REACT_APP_API_URL}/users/create`, action.payload)
.map(data => {
let response = data.response;
if (response.user && response.token) {
return userRegistrationFulfilled();
} else {
return Observable.of(userRegistrationRejected(["Unknown error. Please, refresh page and try again."]));
}
})
.catch(error => {
console.log(error)
let errors = sailsErrors.parseValidationErrors(error.response);
return Observable.of(userRegistrationRejected(!!errors ? errors : ["Unknown error. Please, refresh page and try again."]))
}));
I don't think this code is particularly relevant, though -- this functionality seems fine and was previously working. The problem seems to be in the Sails server - Docker connection which isn't "visible".
I expect that when users enter their information, they will be logged in via the create endpoint of our server (like it used to work). Now, the data is being submitted, but the console is just returning a 404 not found error on the create endpoint of our Sails server.

How to fetch data via http request from Node.Js on AppEngine?

Everything works perfect when I run locally. When I deploy my app on AppEngine, for some reason, the most simple request gets timeout errors. I even implemented retry and, while I made some progress, it still not working well.
I don't think it matter since I don't have the problem running on local, but here's the code I just used for request-retry module:
request({
url: url,
maxAttempts: 5,
retryDelay: 1000, // 1s delay
}, function (error, res, body) {
if (!error && res.statusCode === 200) {
resolve(body);
} else {
console.log(c.red, 'Error getting data from url:', url, c.Reset);
reject(error);
}
});
Any suggestions?
Also, I can see this errors in the Debug:
This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.
────────────────────
The process handling this request unexpectedly died. This is likely to cause a new process to be used for the next request to your application. (Error code 203)
The error 203 means that Google App Engine detected that the RPC channel has closed unexpectedly and shuts down the instance. The request failure is caused by the instance shutting down.
The other message about a request causing a new process to start in you application is most likely caused by the instances shutting down. This message appears when a new instance starts serving a request. As your instances were dying due to the error 203, new instances were taking its place, serving your new requests and sending that message.
An explaination for why it's working on Google Cloud Engine (or locally) is because the App Engine component causing the error is not present on those environments.
Lastly, if you are still interested in solving the issue with App Engine and are entitled to GCP support, I suggest contacting with the Technical Support team. The issue seems exclusive to App Engine, but I can't answer further about the reason why, that's why I'm suggesting contacting with support. They have more tools available and will be able to help investigate the issue more thoughtfully.

Resources