OAjax: how to handle server offline and cache not available scanerio? - oajax.js

I am using oajax.js. Is there a way to handle the case where server is offline and data is also not available in cache?

Normally in given case oajax.js response with it own define error json object in which status is 404 so you can handle this in following way:
$oajax({url: "http://localhost/phonegap/getData.php" , success: function(result){
if(result.error){
//data is not found in cashe
}
},
error : function(err){
console.log(err);
}
});

Related

How can I fix an Axios interceptor causing property 'status' of undefined error

I have a selection to set permissions for elements to global or private. I'm using the Axios interceptor request to handle looking for the permissions field to have data and, if it does, stringify it. The problem is, it causes me to get a "TypeError: Cannot read property 'status' of undefined" when I attempt to reload the program at all. The only "fix" right now is to log out, remove the interceptor, log in, read it, and then run the check again.
Because of this, I can't even get to the home dashboard of the software. If I clear my cookies, I can go back to the login screen, but no further than that after attempting to log in.
Is there something I'm missing for it? below is the interceptor code. If more information or context is needed, please let me know.
export default {
install: (Vue) => {
Vue.$eventBus = new Vue();
Vue.axios.interceptors.response.use(response => {
return response.data;
}, async error => {
if (error.response.status === 401 && error.config.url != '/api/authentication/login') {
var config = await Vue.$configService.find();
window.location = config.accountPortalUrl;
return
}
console.log(error);
Vue.$eventBus.$emit('notifyUser', 'Uh oh, something went wrong!');
return Promise.reject(error);
});
Vue.axios.interceptors.request.use(
config => {
// check request method -> use post if many params
if (config.data.permissions) {
config.data.permissions = JSON.stringify(config.data.permissions);
}
console.log(config);
return config;
}
);
}
};
Looks like your service API is not responding, this might happen if the user is not authenticated . Your error is at line where you check (error.response.status). Its only possible to get an undefined response when the request was interrupted before response. Most probably if you check your browser network pannel you will see that the preflight check for this request causes a 401 network error. Hence because the preflight failed your actual response comes as undefined. You should sanity check first if your server responded with a response or not and then access the response status.
Something like this might help
if (error.response) {
// Request was made and the server responded successfully
// You can now de-structure the response object to get the status
console.log(error.response.status);
} else if (error.request) {
// request was made but not responded by server
console.log(error.request);
}
So, the answer ultimately was something extremely simple.
if (config.data.permissions)
needed to be
if (config.data && config.data.permissions)

How to send multiple Validation Errors to React using Flask and Marshmallow in Backend and Axios for React-Native in Frontend

I am using Marshmallow to validate incoming fields for a simple put request.
Now I am testing the error handling in the frontend to make sure I send the right error messages for the frontend.
I am usually sending data of type
{
password: string,
email: string
}
For now Marshmallow checks if the password is long enough and if the email is of format Email.
I collect all errors in a expect statement and send it to the frontend like this:
except ValidationError as err:
return make_response(
{"errors": err.messages}, status.HTTP_400_BAD_REQUEST
)
with Postman giving me e.g. this response:
{
"errors": {
"email": [
"Missing data for required field."
],
"password": [
"Missing data for required field."
],
}
}
All error messages are therefore collected within the field errors and sent back to the frontend.
When the error is sent back to the frontend I catch my error and all I get is this object:
Object {
"data": null,
"error": [Error: Request failed with status code 400],
}
How do I correctly send or receive the
errors: err.messages
field in the frontend within a make_response error response?
I found the solution to the problem I had here:
github.com/axios/axios/issues/960.
Apparently you have to access the response object or the error object that is send to axios. There is no interceptor needed. What I changed was this line, when resolving the promise to:
try {
resolved.data = await promise;
} catch (e) {
resolved.error = e.response.data;
}
before that I accessed the error with:
try {
resolved.data = await promise;
} catch (e) {
resolved.error = e;
}
The errors are stored within the response.data.

Handling errors if no network is available

I just implemented my first backend file where I fetch some user data, messages and so on.
Now I wanted to include error handling if there is no network available.
I donĀ“t know if I did it right but this was my approach so far:
import axios from 'axios'
const host = process.env.VUE_APP_URL
export default {
person: async function (currentPerson) {
let params = {
currentPerson: localStorage.getItem("person"),
};
if (user) {
params['currentPerson'] = currentPerson;
}
return axios.get(`${host}/api/currentPerson`, {
params: params
})
//catching network errors
.catch (error => {
if (error.response) {
/*
* The request was made and the server responded with a
4xx/5xx error
*/
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
/*
* The request was made but no response was received
*/
console.log(error.request);
} else {
// Something happened in setting up the request and triggered an Error
console.log('Error', error.message);
}
console.log(error)
});
},
In my mounted() function of my main view I fetch the data from my backend file from above:
backend.matches().then(function (response) {
self.contacts = response.data.persons;
});
I tried to check in console if it is working but all I get is the following:
In the catch block I check for
response errors: like 4xx/5xx
request errors: if my network not responding in time
and any other errors
Would this be the right approach to check if a network is available or not? Or does it degrade the user experience when the user checks the error?
My backend file includes more methods.. do I have to write for each method these kind of requests?
In your backend file you don't react whether there is a network connection or not I think.
And only for reference: that is not the backend, but communicates with the backend - the backend is the part of your code what you communicate with, e.g. Laravel code, an API, ...
Try adding the following at the beginning of your catch part:
if (!error.response) {
//network error
console.log('No network connection');
} else if (error.response) {
//the rest of your code
This should print out No network connection in your console.
Run your application, turn off the internet connection and check the console.
These kind of code should always be located in your backend part.
My answer maybe different from your question.
When i create a .net core API with Angular i used three things to check is there network or not?
subscribe to windows's offline/online event
create signalR hub from layout component to API server
API request failed (it means lot of incident, but if 1. or 2. case is true i know what cause 3. case

400 Bad Request when doing a Parse Unity cloud call to user.logIn in Parse.Cloud.Define

When trying to define a Parse Cloud Code server side function to handle login I get 400 Bad Request when I try to call it. When I look at the Parse logs it records the error "Failed with: ReferenceError: user is not defined". But the user is definitely defined!
Below is the definition of the cloud code for LogIn:
Parse.Cloud.define("LogIn", function(request, response)
{
user.logIn(request.params.username, request.params.password,
{
success: function(user)
{
response.success(
{
"success": "Log in successful."
});
},
error: function(user, error)
{
// We must respond with a success in order to access the
// result of the request inside Unity.
response.success(
{
"error": "Log in failed.",
"code": error.code,
"message": error.message
});
}
});
});
From Unity I make this call to the LogIn coud code function:
ParseCloud.CallFunctionAsync<Dictionary<string, object>> ("LogIn", userInfo).ContinueWith (t =>
{
etc.....
}
I get the following error logged in the server side Parse logs when I call the above from Unity using user sashas123 and also student123:
E2014-09-26T17:06:18.001Z] v8: Ran cloud function LogIn with: Input:
{"username":"sashas123","password":"test"} Failed with:
ReferenceError: user is not defined
at main.js:43:5
E2014-09-26T17:38:50.474Z] v10: Ran cloud function LogIn with:
Input: {"username":"student123","password":"test"} Failed with:
ReferenceError: user is not defined
at main.js:43:5
The following snapshot from the Data Browser shows that the above users are definitely defined:
![Parse User class][1]
Is there any issue with calling user.LogIn on the server side through Cloud Code or is this a Unity issue?
It looks like user.logIn should be request.user.logIn :)
I find it's best to handle the case where the function may be called without a logged in user too:
if (request.user.logIn != null)
{
...
}
else
{
response.error("This function must be called with a logged in user!");
}
Hope this help!

Why doesn't dojo.io.script.get() execute the provided error function when receiving a 404?

I am trying to use the following to do a cross-domain get:
dojo.io.script.get({
url: myUrl,
callbackParamName: "callback",
preventCache: true,
load: dojo.hitch( this, loadFunction ),
error: dojo.hitch( this, function() {
console.log('Error!!!');
})
});
The load function runs fine, however, when the server returns a 404, the error function does not run. Can anyone tell me why?
EDIT
After some investigation, I found that a timeout and handler could be implemented in the following way:
dojo.io.script.get({
url: myUrl,
callbackParamName: "callback",
timeout: 2000
}).then(function(data){
console.log(data);
}, function(error){
alert(error);
});
This uses functionality provided by the dojo.Deferred object.
When accessing server with script tags (that what dojo.io.script.get does), status code and headers are not available.
You may try some other ways to detect a problem, like using a timeout and analyzing a content of a script. The latter is problematic for JSONP calls (like in your example).
I realize this is old but I thought I'd share a solution in case others, like I had, come across this thread.
dojo.io.script is essentially adding a <script/> to your html page. So you can try this:
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', myUrl);
script.onerror = function() {
debugger
}
script.onload = function() {
debugger
}
document.getElementsByTagName('body')[0].appendChild(script);
That way if the script fails to load the onerror event is called.
*This may not work in every instance but is a good start