How to programmatically get network errors in AngularJS - javascript

I have the following code in say abcd.js:
$http({url: 'some url' , method: 'POST', data: , headers: {}
}).then(function(response)) {
.............
}, function error(response) {
..............
})
In the case of error the values of response.status = -1,
response.statusText ="". Basically no useful info. However in the Chrome Debugger console output I see:
POST: Some URL/analysis.php net::ERR_NETWORK_IO_SUSPENDED
The chrome debugger extracts the real error from the analysis.php network packet and displays it.
Q1: Why is that the status and statusText dont have useful info?
Q2: Is it possible to get programmatically the network error? In the above failure example I would get it as ERR_NETWORK_IO_SUSPENDED.
Q3: Programmatically is there any other way to get the network error when $http() fails?

Q1: Why is that the status and statusText dont have useful info?
because you cannot reach the server, you won't get useful status code from the server.
Q2: Is it possible to get programmatically the network error?
you can set timeout to $http to catch network problems manually.
Q3: Programmatically is there any other way to get the network error when $http() fails?
take advantage of error callback of $http? (I don't know well about this)

After much Googling I found out that when ever I get the status = -1 that means the server was not reached at all because of some unknown reasons. All the unknown reasons are bundled under one error string ERR_NETWORK_IO_SUSPENDED. I do get a -1 and now I have simply hard coded the error string as ERR_NETWORK_IO_SUSPENDED. For other error code such as 400, 404 the status does get the number bad statuText has the correct string. So this confirmed $http() call is fine. With that said we can close this case. Thanks to all who helped to arrive at this conclusion.

Related

Angular 10 subscribe is failing to post with error code OK(and no other errors shown)

I am new to angular 10 and I am trying to make an http post to a PHP file as shown below
this.http.post(`${environment.server}/path/file.php`, {param1, param2})
.subscribe(
data => {
console.log(JSON.stringify(data));
},
error => {
console.log(error);
this.error = error;
});
The file is successfully called and returns the following JSON as displayed in the console response
{"Email":null,"school_year":2021,"academic_year":"2021"}
When I make the request I am immediately taken to the error state and all the console log is showing below only prints "OK"
console.log(error);
The two questions are the following
Why am getting to the error when the file is successfully returning JSON
Is there a way to get a more helpful error message than just OK
You will need to set the content type to application/json
You would be better off if you used a rest API rather than using php files. .NET Core or Node.JS would give you a better development experience.
It seems that your back-end PHP send the response with status code 400. It should be revised to 200 to get the data in response. When Status code is in Error range like 400, 401, 403 ... http Response will resolved in error or catch part.
In addition if you want just get data, it's better to use GET instead of POST.

error description from http error code - react.js/javascript

I have a Component in my react.js application, which display an error code.
Like this:
Now I'm displaying just a code, along with this what I want to to is - show the reason of this error too. Like this page contains a lot of information about error codes.
How can I do it ?
If I get any error, then I get the error code and use window.location="/bad_request/".concat(err_code);
In my ErrorPage component I've :
componentWillMount() {
this.state.errorCode = this.props.match.params.errorCode;
console.log(this.state.errorCode);
}
Rest is simple.
In common, HTTP response codes are being used for describing a general result of the response. For example, server should return one of 20x codes (200, 201, 202, ...) on some success operation or 40x (400, 401, 401, ...) on client error etc.
That said, code itself won't describe an actual request result in details so you have to do consider an error code only like general reference point.
Answering to you question, I'd suggest you need to take a following steps:
1. Review your server response structure to make it include an actual error message in response body.
2. Review your component structure to retrieve error message from response body to display it (or perform any other required actions)
Basically this error indicating that server didn't receiving complete req. in its time period So it is giving this error So you use increase server timeout as well as you can check with sending less data on server. For more info:
https://airbrake.io/blog/http-errors/408-request-timeout
I wrote this to my java-script file :
let map = new Map();
map.set(400,'Bad Request');
map.set(401,'Unauthorized');
...
When I get redirected to this page, I just get what was the description of the error.
Now I have entered all the data manually, I was just asking if there was any automated way to log these.

Getting "TypeError: Failed to fetch" when the request hasn't actually failed

I'm using fetch API within my React app. The application was deployed on a server and was working perfectly. I tested it multiple times. But, suddenly the application stopped working and I've no clue why. The issue is when I send a get request, I'm receiving a valid response from the server but also the fetch API is catching an exception and showing TypeError: Failed to fetch. I didn't even make any changes to the code and it's the issue with all of the React components.
I'm getting a valid response:
But also getting this error at the same time:
fetch(url)
.then(res => res.json())
.then(data => {
// do something with data
})
.catch(rejected => {
console.log(rejected);
});
When I remove credentials: "include", it works on localhost, but not on the server.
I tried every solution given on StackOverflow and GitHub, but it's just not working out for me.
This could be an issue with the response you are receiving from the backend. If it was working fine on the server then the problem could be within the response headers.
Check the value of Access-Control-Allow-Origin in the response headers. Usually fetch API will throw fail to fetch even after receiving a response when the response headers' Access-Control-Allow-Origin and the origin of request won't match.
I understand this question might have a React-specific cause, but it shows up first in search results for "Typeerror: Failed to fetch" and I wanted to lay out all possible causes here.
The Fetch spec lists times when you throw a TypeError from the Fetch API: https://fetch.spec.whatwg.org/#fetch-api
Relevant passages as of January 2021 are below. These are excerpts from the text.
4.6 HTTP-network fetch
To perform an HTTP-network fetch using request with an optional credentials flag, run these steps:
...
16. Run these steps in parallel:
...
2. If aborted, then:
...
3. Otherwise, if stream is readable, error stream with a TypeError.
To append a name/value name/value pair to a Headers object (headers), run these steps:
Normalize value.
If name is not a name or value is not a value, then throw a TypeError.
If headers’s guard is "immutable", then throw a TypeError.
Filling Headers object headers with a given object object:
To fill a Headers object headers with a given object object, run these steps:
If object is a sequence, then for each header in object:
If header does not contain exactly two items, then throw a TypeError.
Method steps sometimes throw TypeError:
The delete(name) method steps are:
If name is not a name, then throw a TypeError.
If this’s guard is "immutable", then throw a TypeError.
The get(name) method steps are:
If name is not a name, then throw a TypeError.
Return the result of getting name from this’s header list.
The has(name) method steps are:
If name is not a name, then throw a TypeError.
The set(name, value) method steps are:
Normalize value.
If name is not a name or value is not a value, then throw a TypeError.
If this’s guard is "immutable", then throw a TypeError.
To extract a body and a Content-Type value from object, with an optional boolean keepalive (default false), run these steps:
...
5. Switch on object:
...
ReadableStream
If keepalive is true, then throw a TypeError.
If object is disturbed or locked, then throw a TypeError.
In the section "Body mixin" if you are using FormData there are several ways to throw a TypeError. I haven't listed them here because it would make this answer very long. Relevant passages: https://fetch.spec.whatwg.org/#body-mixin
In the section "Request Class" the new Request(input, init) constructor is a minefield of potential TypeErrors:
The new Request(input, init) constructor steps are:
...
6. If input is a string, then:
...
2. If parsedURL is a failure, then throw a TypeError.
3. IF parsedURL includes credentials, then throw a TypeError.
...
11. If init["window"] exists and is non-null, then throw a TypeError.
...
15. If init["referrer" exists, then:
...
1. Let referrer be init["referrer"].
2. If referrer is the empty string, then set request’s referrer to "no-referrer".
3. Otherwise:
1. Let parsedReferrer be the result of parsing referrer with baseURL.
2. If parsedReferrer is failure, then throw a TypeError.
...
18. If mode is "navigate", then throw a TypeError.
...
23. If request's cache mode is "only-if-cached" and request's mode is not "same-origin" then throw a TypeError.
...
27. If init["method"] exists, then:
...
2. If method is not a method or method is a forbidden method, then throw a TypeError.
...
32. If this’s request’s mode is "no-cors", then:
1. If this’s request’s method is not a CORS-safelisted method, then throw a TypeError.
...
35. If either init["body"] exists and is non-null or inputBody is non-null, and request’s method is GET or HEAD, then throw a TypeError.
...
38. If body is non-null and body's source is null, then:
1. If this’s request’s mode is neither "same-origin" nor "cors", then throw a TypeError.
...
39. If inputBody is body and input is disturbed or locked, then throw a TypeError.
The clone() method steps are:
If this is disturbed or locked, then throw a TypeError.
In the Response class:
The new Response(body, init) constructor steps are:
...
2. If init["statusText"] does not match the reason-phrase token production, then throw a TypeError.
...
8. If body is non-null, then:
1. If init["status"] is a null body status, then throw a TypeError.
...
The static redirect(url, status) method steps are:
...
2. If parsedURL is failure, then throw a TypeError.
The clone() method steps are:
If this is disturbed or locked, then throw a TypeError.
In section "The Fetch method"
The fetch(input, init) method steps are:
...
9. Run the following in parallel:
To process response for response, run these substeps:
...
3. If response is a network error, then reject p with a TypeError and terminate these substeps.
In addition to these potential problems, there are some browser-specific behaviors which can throw a TypeError. For instance, if you set keepalive to true and have a payload > 64 KB you'll get a TypeError on Chrome, but the same request can work in Firefox. These behaviors aren't documented in the spec, but you can find information about them by Googling for limitations for each option you're setting in fetch.
I've simply input "http://" before "localhost" in the url.
If your are invoking fetch on a localhost server, use non-SSL unless you have a valid certificate for localhost. fetch will fail on an invalid or self signed certificate especially on localhost.
Note that there is an unrelated issue in your code but that could bite you later: you should return res.json() or you will not catch any error occurring in JSON parsing or your own function processing data.
Back to your error: You cannot have a TypeError: failed to fetch with a successful request. You probably have another request (check your "network" panel to see all of them) that breaks and causes this error to be logged. Also, maybe check "Preserve log" to be sure the panel is not cleared by any indelicate redirection. Sometimes I happen to have a persistent "console" panel, and a cleared "network" panel that leads me to have error in console which is actually unrelated to the visible requests. You should check that.
Or you (but that would be vicious) actually have a hardcoded console.log('TypeError: failed to fetch') in your final .catch ;) and the error is in reality in your .then() but it's hard to believe.
In my case I got "TypeError" when using online JS tools like jsfiddle or stackblitz and the problem was that my url was http instead of https.
Behind the scenes the XHR client sends an HTTPOPTIONS request, called pre-flight, to look for certain security permission headers, called CORS Allow headers. If the required headers are not found (as in you might not have the necessary permissions), TypeError is the result since it has not actually tried to send your POST/GET request. You can observe this behavior in the browser console: it looks like the browser makes two requests to the same location, first having the HTTP Method: OPTIONS.
In my case, this error was caused by the missing always parameter to the add_header directive of nginx.
For example, when our backend was sending an error response, such as in PHP header('HTTP', ERROR_CODE), was resulting in CORS headers missing from response.
As the docs states about add_header directive
Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0).
and about always parameter
If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.
Adding the always parameter to any required headers fixed the issue for me, like so:
add_header HEADER_NAME "HEADER_VALUE" always;
I spent a few hours on this error in my project involving Vue / Nuxt 3.0.0 and Supabase Edge Functions. I finally realized that I wasn't including the corsHeader on the success response, only the error response. So everything worked, and it returned Status Code 201, but it popped as error. Simple solution to a frustrating problem. Left this here because my search brought me back here multiple times. Hope it helps!
See how they add ...corsHeaders to both the successful and error responses here: https://supabase.com/docs/guides/functions/cors
I was getting this issue since I have not added CORS in my flask app. I need to add it, then it worked, here are the lines:
...
from flask_cors import CORS
def create_app(test_config=None ):
app = Flask(__name__)
app.config.from_object('config') # Import things from config
CORS(app)
# CORS Headers
#app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,true')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
return response
...
This question comes up first when googling the same error, so sharing the solution here for others:
If you use Sentry, you need to add the 'sentry-trace' value to your servers Access-Control-Allow-Headers list.
Issue here https://github.com/getsentry/sentry-javascript/issues/3185
after struggling a few hours on that error, I would like to share my solution
<a
:href="some_props_with_default_value"
#click="externalCalculationViaFetch()"
>
Calculate
</a>
There was a problem with some_props_with_default_value that generating a page refresh.
The page refresh was canceling the fetch request before getting a response and raising this error.
Went back to normal when fixing the page refresh :
<a
#click="externalCalculationViaFetch()"
>
Calculate
</a>
Hope it helps someone.
In my case I was trying to make fetch requests to my Django API via localhost and I was able to make it work by changing my URL from:
var url = "http://127.0.0.1:8000/";
to:
var url = "http://localhost:8000/";

Google Chrome shows error in console, although error handling is defined within the function

I have the following function, which requests data from Google Analytics API and gets a response as a JSON Array:
// Query the Core Reporting API from Google Analytics with the defined variables
function requestResponse() {
gapi.client.analytics.data.ga.get({
'ids': 'ga:' + $('input[name="hiddenProfileId"]').val(),
'start-date': $('input[name="hiddenStartDate"]').val(),
'end-date': $('input[name="hiddenEndDate"]').val(),
'metrics': metricsArrayOutput.join(","),
'dimensions': dimensionsArrayOutput.join(",")
// If response isn't an error, then change div background to pale green and show a "Tree View" of the JSON obtained
}).then(function(response) {
$("#responseOutput").empty();
$("#responseOutput").JSONView(response.result, {collapsed: true});
$("#responseOutput").css("background-color", "#bef7be");
// Handle error: change div background to pale red and show the error Objects of the JSON obtained
}, function(errorResponse) {
$("#responseOutput").empty();
$("#responseOutput").JSONView(errorResponse.result.error, {collapsed: false});
$("#responseOutput").css("background-color", "#FBDDDD");
alert("bad things happen to everyone");
})
}
It's the first time that I use the then() method, and although at the beginning I had some problems trying to handle the error responses (because initially I defined only the argument for success case), it works really good now and I love how easy I can handle all the not 200 HTTP Responses.
However, in Google Chrome (v. 47.0.2526.106) Console I am getting a weird "GET error" when the response isn't a 200 HTTP Response:
GET
https://content.googleapis.com/analytics/v3/data/ga?{parameters_that_result_in_error_response}
400 (OK)
{parameters_that_result_in_error_response} is the combination of variables sent to the API that generates an error response.
As I said, the function works and its general goal is achieved, but I don't understand why this error is being shown. When the http response is a 200 one, nothing is sent to console, so I can imagine that the .then() is sending this error to the console itself, although it's handled in the code some lines after. Do you know how to resolve this incongruence?
Note: No error is shown in IE or Firefox.

RESTful Get Request with Angular & NodeJS Express

I'm just following tutorials and figuring out how to handle get requests in NodeJS.
Here are snippets of my code:
NodeJS:
router.get('/test', function(request, response, next) {
console.log("Received Get Request");
response.jsonp({
data: 'test'
});
});
Angular:
$http.get("http://localhost:3000/test").
success(function(response) {
alert("OK");
}).
error(function(response) {
alert("FAIL");
});
If I try to access the link directly # localhost:3000/test, I'm able to receive the JSON message correctly. But when I use angularJS $http call, the request always fails and I'll find this error in the network inspector (Response)
SyntaxError:JSON.parse:unexpected end of data at line 1 column 1 of
the JSON data
The reason for that is because the response is empty but the response code is 200 in both cases.
I've tried searching for hours but maybe someone can enlighten me on this?
you could try and send
res.send('test')
and then on your http request you can use 'then'
$http.get("http://localhost:3000/test").then(function(res) {
console.log(res);
})
unlike success, then will give you a complete object (with 'test' - string as res.data)
success will bring you only the data;
then will bring you the whole object (with the status and such)..
now about that jsonp .. it's used to override a json response. you could simply use 'res.json({data: 'test'})' and it should also work for you..
hope it helps
You're using jsonp in node, which you probably don't need to. This adds extra characters to the response and so the JSON parser fails to parse (that's what the error is telling you, the JSON is malformed)
Try changing the server to look like
response.json({
data: 'test'
});
If you look in the Network pane of the developer tools, you should be able to see the raw response. It should look something like:
{"data" : "test"}

Categories