Check HTTP status code in the Axios promise catch block VueJs - javascript

New to VueJS. I have the following code that retrieves data from the Controller using axios:
SubmitForm: function () {
axios({
method: 'post',
url: '/Home/SubmitedForm',
data: { "Fields": this.$data }
}).then(res => {
alert('Successfully submitted the form ');
window.close();
}).catch(err => {
if (err.response.status == 409) {
alert(`Already exists. See details: ${err}`)
}
else {
alert(`There was an error submitting your form. See details: ${err}`)
}
});
When the Controller method SubmittedForm returns 409, I want to throw a specific alert else just throw a generic alert. Based on this page: https://gist.github.com/fgilio/230ccd514e9381fafa51608fcf137253 I wrote the above code. However, even thought the http status returned is 409, it still show the generic alert.
I'm pretty sure I'm missing some understanding here. Can someone please help me find out what am I doing wrong here?
Works as expected on localhost but after publishing on azurewebsites it again displays the generic error.

Maybe your API endpoint brakes CORS policy, you can't read status of such error then (despite the fact that it is visible in Networks tab in dev tools).
You can install a browser extension like "CORS everywhere" to test if it works then, but any call to API blocked by CORS will show a warning/error in the browser's console by default.

Probably because err.response.status is a string and you are comparing to number

Related

I'm receiving a 400 bad request error: "A non-empty request body is required" from my fetch request, despite my fetch request having a body

Everytime I make a fetch request from my frontend using the following js code I receive a 400 Bad request status. The body of the response has an error object saying: "A non-empty request body is required".
When I inspect the request section on my devtools network tab it says "no payload for this request". So it looks to me it's not sending the body section of my Fetch.
It does reach the .then() method afterwards.
This is the Typescript Code:
fetch(`api/person/${person.id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(person)
})
.then(() => this.router.navigate(["/"]))
this is the C# backend:
[HttpPut("{id}")]
public IActionResult Put(int id, Person person)
{
person.Id = id;
try
{
var updatedPerson = _personRepository.Update(person);
if (updatedPerson != null)
{
return Ok(updatedPerson);
}
return NotFound();
}
catch (ArgumentNullException)
{
return BadRequest();
}
}
Note that the request doesn't even reach this controller. No break points will be reached if I place any here.
This is a single page application I run from Visual Studio 2019.
It works with postman however, returning the 200 Ok status code and an object back, and reaching backend breakpoints. The request URL contains the int id and the body containing a Json object.
Okay this is not a question that has a clear answer.
Here are steps you could need to take to find out:
Make sure in your fetch request the argument person is really exist, just do console.log(person) before fetch
Make sure server accepts 'application/json' type content. Though in this case the response code should have been different.
Check the response headers, and are the origins of back end and front end are the same? What you need to see are the following:
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Origin: *
Postman works as a native app on your PC and has different way of sending requests rather than your browser, sometimes this causes unclear results.
Here's a way to test what is happening.
Go to your main web site (http://localhost:5001 or whatever) in your
browser
Open up Browser Dev Tools (F12 in most browsers)
copy / paste the following fetch (code below) into your Dev console
& press
What happens? Do you get data back (printed in console)?
This will probably get you to the next step you need to take.
fetch("api/person/1")
.then(response => response.json())
.then(data => console.log(data));

403 when making axios POST request

I have a feature that loads a map onto a page, and 5% of the time I'm hit with a 403 error and the map data doesn't load properly. I've had a very difficult time with triggering the error, but I was able to catch it and take screenshots (see below).
When the page refreshes, a GET request occurs that loads the right data, and then a POST request occurs that loads the right map. There are multiple pages, each with their own content and maps, and a user can easily navigate between pages.
i.e. When the Mordor page loads, the data for the Mordor map loads simultaneously. When I navigate to the Lothlorien page, the data for the Lothlorien map loads.
Any thoughts on what's causing this? As I said, although this error happens rarely I do want to get to the bottom of it, in order to prevent future complications down the line.
Notes:
I used to have an issue to where the 403 error happened frequently (if the page was idle), but I resolved it by doing a if resp.status === 403, window.location.reload. That fixed the problem, but I've wondered if the issue I'm experiencing now is related to it and "leaking through", so to speak.
webpack-internal shows up in the console (see screenshots), but searching for 403 errors with webpack comes up short.
I'm using empty() throughout the project, so that the old data doesn't remain on the page.
async function loadMaps(){
let ret = axios.post( // ${location} is referenced at an earlier point, and always works
`${_Something}/something/_api/web/lists/getbytitle('Middle Earth Maps')/GetItems`,{
"query": {"__metadata": {"type":"SP.CamlQuery"}, "ViewXml": `<View><Query><Where><Eq><FieldRef Name='MiddleEarthMaps'/><Value Type='TaxonomyFieldType'>${location}</Value></Eq></Where></Query></View>`}
}, {
method: "POST",
credentials: "include",
mode: "no-cors",
headers: {
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
}
}).then(resp => {
console.log(resp.status)
// in here there's other code that behaves as intended (95% of the time)
}).catch(err => {
if (err.status === 401 || err.status === 403) { // I use this for the main page of the project, and it works as intended
window.location.reload();
}
console.log("Error during loadMaps");
console.log(err);
return false;
});
return ret;
}
403 in the console
The debugger
Local in the debugger
I don't have enough reputation to comment, so I'll put my two cents below:
According to MDN Web Docs:
The HTTP 403 Forbidden client error status response code indicates that the server understood the request but refuses to authorize it.
If the requests are consistent, but responses are not, chances are error comes from server.
It might be reasonable to consult the server documentation or contact maintainer directly.
Maybe check if the server is rate-limiting your request, or the server is unstable. If the problem persists, report the bug to maintainer.

Console log raw data of a failed Axios get request

I would like to make an Axios get request to a private server running Flask.
In case there is an internal error in the back-end it returns an response object and an error code.:
response_object = {
"Success": False,
'error': err.message
}
return response_object, 400
The served response_object should be accessible the front-end (React.js).
axios
.get(`http://127.0.0.1:5000/data`, {
data: null,
headers: { "Content-Type": "application/json" }
})
.then(response => {
console.log(response);
})
.catch(function(error) {
console.log(error.toJSON());
});
I would expect the error to include the response object. If the URL is accessed manually in the browser the error data is visible. If there is no error in the back-end the get requests works properly.
After googling for some time I found some issues that might relate to the mentioned problem. (That is why empty data is passed in the a get request).
https://github.com/axios/axios/issues/86
https://github.com/axios/axios/issues/86
Please note that I am self taught so I might miss something obvious here. Thank you all and all the best.
I'll copy/paste my comment here so other can easily see the answer for the question
if it's a 400 status code that it's throwing (you can confirm by using the Network tab in your browser), it will fall into the catch block, the only concern is the toJSON() call... just do a simple console.log(error.message) to check if you ever get there...
I leave you a simple example so you see the catch in action
more information:
in Axios, the response text is in response.data
if you are receiving a JSON, the response.data will be automatically parsed
you do not need to pass data: null as that's the default behavior, and it's not used in a GET call (you won't pass a body in a GET call)

$.ajax() returns syntax error: Unexpected end of json input

So I'm working on a website where I have to implement a chat, currently the whole thing is running on localhost.
I'm getting this error:
SyntaxError: Unexpected end of JSON input
and can't figure out why. I have googled a little but can't find an answer, that actually works. I actually did this yesterday, on another computer and that worked super, but today it won't work and I can't figure out why.
Thank you for the great answers.
$(function() {
updateChat("updateChat", null);
$(".chat-form").submit(function(event) {
event.preventDefault();
if ($(".chat-form input").val() != "") {
updateChat("sendMessage", $(".chat-form input").val());
}
});
setInterval(function() {
updateChat("updateChat", null);
}, 3000);
function updateChat(method, message) {
$.ajax({
type: "POST",
url: "action/chat.php",
data: {
function: method,
message: message
},
dataType: "json",
success: function(data) {
console.log(data);
},
error: function (request, status, error) {
console.log(error);
}
})
}
})
Most likely there's an error or warning in your PHP code being displayed, and because you are expecting only json, that causes the syntax error.
There are a few ways to find out what's going on:
open the developer console in your browser and see what the response is the network tab
check your PHP error log
temporarily change your dataType to html and you'll see your console.log(data)
I was getting this error due to my backend php function NOT returning a response as it should have been. It was returning nothing. My parent function that should have been returning the response was calling a child function that WAS returning a response, but the parent function wasn't passing that child return back to the ajax call.
Another possible culprit for these type of errors could be an improper python "shebang" on your back-end (server side) script.
In my particular case I had ajax call to python cgi script via Apache web server and I could not find a more descriptive error message at front-end debug tools. However, Apache logs indicated that the back-end script had problems importing a one of the python scripts because the interpreter did not recognize it. After checking the "shebang" of that back-end script sure enough it had the wrong interpreter specified because I just copied a template file over and forgot to modify it..
So, check your "shebang" at the top of your script to make sure it points to correct interpreter. Example:
For MVC controller you must return a valid JsON
return new JsonResult() { Data = new { test = 123 } };
instead of
return new JsonResult();

Fetching HTTP Header Params

I'm trying to write a piece of Zap code with Run JavaScript to test the HTTP header response of a URL GET. Specifically, I'm interested in the return status and the location (basically, if it's a 302, want to know what the redirect location is).
fetch('https://www.example.com/', { method: 'GET', redirect: 'manual' })
.then(function(res) {
return res.json();
})
.then(function(json) {
var output = {status: json.status, location: json.headers.get('location')};
callback(null, output);
})
.catch(callback);
I've tried the above but (a) the test always returns rawHTML (which suggests it's following a the redirect, and (b) the output variables in the Send Outbound Zap step don't pick up anything useful (again, "Raw HTML", "ID", "Runtime Meta Logs", etc. but nothing about my headers).
You may not be able to access the Location header due to the same origin policy in most browsers: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
Furthermore, you can't stop the AJAX call from following a redirect, so that may cause you issues: How to prevent jQuery ajax from following a redirect after a post?
It looks like you are using the new built-in fetch function: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
If so, in the provided example, I dont think you need the .json() call. I got the code to run like like below, but there is no redirect at example.com so not sure exactly how your situation will handle. Also, keep in mind the same-origin policy which will likely prohibit you from accessing location header.
var callback = function(a,b){
console.log(a,b)
};
fetch('https://www.example.com/', { method: 'GET', redirect: 'manual' })
.then(function(res) {
console.log (res)
var output = {status: res.status, location: res.headers.get('location')};
callback(null, output);
})
.catch(callback);
If you control the server resource, then you could possibly do something on the server, like adding another header that won't be blocked, many sites do that adding a X-Location option that browsers don't block.
Since we're using https://github.com/bitinn/node-fetch#options under the hood - specifically the redirect: 'follow' option. It even offers the exact "set to manual to extract redirect headers".
You might try experimenting with a local Node.js REPL to figure it out. If you see it working locally but not in Zapier - just file a bug to contact#zapier.com.
I managed to get this code working:
fetch('https://www.example.com/', { method: 'GET', redirect: 'manual', follow: 0 })
.then(function(res) {
var output = {status: res.status, location: res.headers._headers.location};
callback(null, output);
})
.catch(callback);
The underlying issue appears to be (as evidenced by the output variables with "id" and "rawHTML") that the fields were somehow "stuck". When I (1) deleted the Run Javascript step, (2) reinserted a new one with the above code, the correct output fields were then returned and subsequently became available to the Send Outbound Email step.

Categories

Resources