I have a code for reading a json file in JS. I had the code wrapped in "try catch" blocks.
The way I get it - if the file is not found for some reason, it should enter the "catch" block.
Yet, if "lang" is undefined - it throws a 404:
" GET --<-server->--/settings/Lang_undefined.json 404 (Not Found) "
without ever entering the "catch" block.
can anyone help me understand why it is so?
Thank you!!
function loadDic() {
try {
$.getJSON(SERVER_URL + "settings/Lang_" + lang + ".json", function(data) {
dic = data["dictionary"];
setLanguage();
});
} catch (err) {
return false;
}
}
Since you appear to be making an ajax request (not a jsonp request,) you can catch the error using the error callback.
function loadDic() {
$.getJSON(SERVER_URL + "settings/Lang_" + lang + ".json", function(data) {
dic = data["dictionary"];
setLanguage();
}).fail(setLanguageFail);
}
Ajax is asynchronous.
The getJSON function sends an HTTP request.
It sends it successfully
The try is successful
The Ajax then gets a response saying that the server had a 404 error
You haven't specified an error event handler, so nothing happens
The 404 error does not cause an exception to be thrown (it is an HTTP error, not a JavaScript error) and there is nothing waiting to catch an exception at that time anyway.
If you want to do something in the event of an error, then specify a function to handle it (you can't do this with getJSON(), you should use ajax() instead). Note that you cannot return (based on this) from the function that included the getJSON call.
Related
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.
everyone!
I got a problem: I'm trying to validate registration form. Totally, it works ok, but I need to validate form via server. In my case, for example, I need to figure out if email is already taken.
I tried to fetch and async/await syntax, but problem is still the same:
DOMException: "The operation was aborted. "
The way I understand it right now is readableStream (what actual response body is) is locked. So the wrong error is thrown, and I cannot get server response.
try {
const response = await fetch(options.url, options.requestOptions);
const body = await response.json();
if (options.modifyDataCallback instanceof Function) {
body.data = options.modifyDataCallback(body.data);
}
return body.data;
} catch (error) {
throw error;
}
How do I see the solution? I send request and recieve some server error like
code: email_in_use
message: Email '...' is already in use.
Then I need to throw error and catch it in other place in order to show corresponding error message to client.
In browsers network tab I do receive what I want to receive, but can't get the same JSON-response in my code.
Google chrome provided more information: net::ERR_HTTP2_PROTOCOL_ERROR 200.
And the problem was on backend. It is written in C# and API method returned Task. The problem was solved by adding async/await for this method.
I wrote a function that keeps returning an Access-Control-Allow-Origin error. This is actually fine for me; I don't want to fix this. I just want to catch it so I can read its message in my program.
All the code that causes the error to be thrown is within my try block, and my catch block displays the error's string message. However, when I run the code, no error is caught, and the error shows up in red in the console. How do I catch this error and store its message?
try {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (this.status < 400 && this.status >= 300) {
console.log('this redirects to ' + this.getResponseHeader("Location"));
} else {
console.log('doesn\'t redirect');
}
}
xhr.open('HEAD', $scope.suggLink, true);
xhr.send();
} catch(e) {
console.log('Caught it!');
console.log(e.message);
}
While browsers will log a more-detailed error message to the console, you can’t access that from your code. See https://bugs.chromium.org/p/chromium/issues/detail?id=118096#c5:
The details of errors of XHRs and Fetch API are not exposed to JavaScript for security reasons.
As far as the what specs actually require here, the Fetch spec is what defines the details of the “status message” to provide in case of an error — even if XHR is used instead of the Fetch API (the XHR spec references the Fetch spec). And for any network error or response blocked by the browser, the Fetch spec requires that the status message be “the empty byte sequence”:
A network error is a response whose status is always 0, status message is always the empty byte sequence, header list is always empty, body is always null, and trailer is always empty.
So all you can get back from any error you can catch is “TypeError: Failed to fetch” or such.
If you’re using XHR, all you have for handling an error is the onerror event handler:
xhr.onerror = function() { console.log("Error occurred but I dunno what exactly.")}
jquery version of above (sideshowbarker's) workaround for CORS error:
let sURL = 'https://www.mocky.io/v2/5185415ba171ea3a00704eed';
$.getJSON(sURL, function (json)
{
console.log('json from web-service ->', json);
})
.fail(function()
{
console.log("error - could not get json data from service");
});
I'm using Angular to send a post request with the $http service. I am doing all of the data validation of the form in Angular prior to sending the post request. However, there is one validation I am doing in PHP of whether the user already exists in the database. How do I purposefully invoke an error (in the php file) so that the Angular error callback is triggered instead of the success callback? Should I purposefully throw an exception?
IF the intent is to throw an exception, does the exception message get passed into the data parameter for the Angular error callback function?
Based on the comments to my question, I just did the following to my code:
if (duplicateUsers($username) > 0) {
return http_response_code(400); // successfully generated an error in
// the $http AngularJS servicces
} else {
// other code
}
You can chain your promises. The first promise will check the success content and that's also where you can throw an exception. This will cause the subsequent promises to return failure.
Here's a jsbin example.
angular
.module('app', [])
.run(function($http) {
var from$http = $http
.get('www.google.com') //makes a request to www.google.com
.then(function(response) {
console.log('data was successfully retrieved from google');
throw "from success handler"; //if has error, then throw "duplicated user"
});
from$http.then(function() { // this then block is handling the previous exception
console.log('this success block is never called');
}, function() {
console.log('inside error block even tho success was returned from www.google.com');
});
});
I'm trying to check whether an URL returns 404, 403 etc when including a Javascript file. It works ok, but I still get an error in "Chrome developer tools".
This is my code:
(function() {
try
{
var ml = document.createElement('script');
ml.type = 'text/javascript';
ml.async = true;
ml.id = 'monoloop_invoke';
ml.onerror = function(){alert('File does not exist');};
ml.src = 'http://somedomain.com/somefile.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ml, s);
}
catch(err)
{
alert('Error: '+err);
}
})
();
If the file does not exist it shows the error "File does not exist" from the ml.onerror function. This is all good. But the problem is that I still get an error line in my console like:
GET http://somedomain.com/somefile.js 403 (Forbidden)
and the try/catch does not catch this error.
Anyone knows how to solve this? Or is there another way of testing if a URL exists before including it? I cannot use AJAX as I need to use this in a cross-domain fashion. I could use jQuery if necessary.
EDIT: It does not show an error in IE, so i guess this maybe just relates to the way chrome reports issues. Does anyone see a more elegant solution for checking if a file exisists without genreting anything in the console.
jQuery.getScript( url, [ success(data, textStatus) ] )
Description: Load a JavaScript file from the server using a GET HTTP request, then execute it.
url
A string containing the URL to which the request is sent.
success(data, textStatus)
A callback function that is executed if the request succeeds.
To catch the errors use the ajaxError event:
http://api.jquery.com/ajaxError/