I am making a http request to a url which is returing a 500 error response(This is the expected behavior). But this is error is getting captured in the success function instead of error function.
$http.get("myUrl")
.then(function (response) {
console.log(response);
}
.function (error) {
// Handle error here
});
Please help in understanding this and the correct way to use this.
It should be either:
$http.get("myUrl")
.then(function (response) {
console.log(response);
}
,function (error) {
// Handle error here
});
Or
$http.get("myUrl")
.then(function (response) {
console.log(response);
})
.catch (function(error) {
// Handle error here
});
If this is angulars $http, it's supposed to be something like this:
$http.get("myUrl")
.then(
function (response) {
console.log(response);
},
function (error) {
// Handle error here
}
);
You want two functions as your arguments to then(). The first is your successCallback, the second your errorCallback.
As an alternative you may add an catch() to your promise chain. Which is easier to read and prevents errors like yours.
I had an interceptor in my application which was causing the problem.
All my error responses were intercepted and returned without a status. Below is the code.
return {
'responseError': function(config) {
if(config.status===401){
//Do Something
return config;
}
return config;
}
}
Changing the return statement to return $q.reject(config); started returning the correct status.
Related
I've had this problem for almost a day and I don't know what else to do to solve it.
Dialogflow Fulfillment in Dialogflow ES just doesn't want to make any HTTP calls at all. I'm always getting this error: No responses defined for platform: DIALOGFLOW_CONSOLE
My entired code is below. The function that crash everything is:
function simpleGet(requestUrl) {
axios.get(https://eo1lbzchsaeazi9.m.pipedream.net/)
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
}
function simpleGet(requestUrl) {
axios.get(https://eo1lbzchsaeazi9.m.pipedream.net/)
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
}
sorry, there is some context missing here.
do you see the error message when trying to use fullfilments (ie. one API call to get on a backend an answer to a customer interaction?
Also, another clarifying question - is it Dialogflow ES or CX?
I've seen some developers struggling with this error and some of them fixed it by updating the package for fulfillments as described here: https://github.com/dialogflow/dialogflow-fulfillment-nodejs/issues/322
In the js-data library, I have added a custom query with the addAction() method as shown here. Now when my server returns a 4xx error code upon calling that custom action, an error is thrown but the server response (which is send) is nowhere to be found:
store.getMapper('school').getTeacherReports(1234, {
basePath: 'reports'
}).then(function(response) {
console.log('response', response.data)
}).catch(function(err) {
console.log('err', err);
})
How should I handle this? Is there some method I don't know of that I should use? I already tried the response and responseError properties in the addAction() according to the docs.
The then function can take two parameters:
then(
onSuccess: Function,
onRejection: Function
)
So here is how you can handle the rejection due to the 4xx error:
store.getMapper('school').getTeacherReports(1234, {
basePath: 'reports'
}).then(
function (response) { // on success
console.log('response', response.data);
},
function (error) { // on error
console.error(error);
},
)
This has to do with axios: The rejected error object indeed has the response as a property (source code) but it doesn't appear as such in console outputs because error objects are shown differently in the console.
The following shows the underlying properties:
store.getMapper('school').getTeacherReports(1234, {
basePath: 'reports'
}).then(function(response) {
console.log('response', response.data)
}).catch(function(err) {
let errorObject = JSON.parse(JSON.stringify(error))
console.log(errorObject)
});
I've only recently looked at promises (JS not being my forte) and I'm not sure what the proper way to do this is. Promises are supposed to prevent right-drifting code but when I end up with somewhat complex logic I end up nested far too deep anyway, so I'm convinced I'm doing it wrong.
If I'm returning both successes and failures as json values, and I want to handle malformed json as well, I immediately think to do something like this:
fetch('json').then(function (result) {
return result.json();
}).catch(function (result) {
console.error("Json parse failed!");
console.error(result.text);
}).then(function (wat) {
// if (!result.ok) { throw...
}).catch(function (wat) {
// Catch http error codes and log the json.errormessage
});
Of course, this won't work. This is stereotypical synchronous code. But it's the first thing that comes to mind. Problems I can see:
How do I get both the response and the json output?
How do I get separate control flow for errors and successes?
How do I catch a json parse error on both types of response?
My best attempt involves nesting to the point where I might as well be using callbacks, and it doesn't work in the end because I still haven't solved any of the above problems:
fetch('json').then(function (response) {
if (!response.ok) {
throw response;
}
}).then(
function (response) {
response.json().then(function (data) {
console.log(data);
});
},
function (response) {
response.json().then(function (data) {
console.error(data.errormessage);
});
}
).catch(function () {
console.error("Json parse failed!");
// Where's my response????
});
What's the "Right" way to do this? (Or at least less wrong)
If you want to call response.json() anyway (for successful and failed response) and want to use the response together will the response data. Use Promise.all:
fetch('json')
.then(response => Promise.all([response, response.json()]))
.then(([response, data]) => {
if (!response.ok) {
console.error(data.errormessage);
} else {
console.log(data);
}
})
.catch(err => {
if (/* if http error */) {
console.error('Http error');
} else if (/* if json parse error */)
console.error('Json parse failed');
} else {
console.error('Unknown error: ' + err);
}
});
You shouldn't use exceptions for control flow in Promises any more than you should when not using Promises. That's why fetch itself doesn't just reject the promise for status codes other than 200.
Here's one suggestion, but the answer will necessarily depend on your specific needs.
fetch('json').then(function (response) {
if (!response.ok) {
response.json().then(function (data) {
console.error(data.errorMessage);
});
return ...;
}
return response.json().catch(function () {
console.error("Json parse failed!");
return ...;
});
}).catch(function (e) {
console.error(e);
return ...;
});
In my Angular app I have a login function. But when I send wrong credentials and response come with status 401: Bad Credentials (there's even response.status = 401) it still goes to success.
So I'm getting $notify "Success login and then html error page in my interceptor. That's confusing. I'm not sure what I've done to create this mess.
this.getTokenCustom = function (user) {
$http.post('/login',
JSON.stringify({username: user.username, password: user.password}))
.then(
function success(response) {
localStorage.setItem('token', response.data.token);
$.notify({message: "Success login"},{type:'success'});
$state.go('roles');
},
function error(data) {
console.log(data);
$.notify({message: data.data.message},{type:'danger'});
}
);
};
UPD
this.getTokenCustom = function (user) {
$http.post('/login',
JSON.stringify({username: user.username, password: user.password}))
.then(
function success(response) {
localStorage.setItem('token', response.data.token);
$.notify({message: response.status + " Success login"},{type:'success'});
$state.go('roles');
},
function error(data) {
console.log(data);
$.notify({message: data.data.message},{type:'danger'});
}
);
};
The likely cause of this is that you may have a custom interceptor that doesn't handle error conditions properly.
This post can point you on the right direction: http://www.jamessturtevant.com/posts/AngularJS-HTTP-Service-Success-Handler-400-Response-Code-and-Interceptors/
To quote the post:
When you handle the requestError or the responseError for a interceptor and you wish to pass the error on to the next handler you must use the promise api to reject the message:
$httpProvider.interceptors.push(function($q) {
return {
'requestError': function(rejection) {
// handle same as below
},
'responseError': function(rejection) {
if (canRecover(rejection)) {
// if you can recover then don't call q.reject()
// will go to success handlers
return responseOrNewPromise;
}
// !!Important Must use promise api's q.reject()
// to properly implement this interceptor
// or the response will go the success handler of the caller
return $q.reject(rejection);
}
};
});
A similar issue to yours was reported on Angular's Github repository and the issue had to do with a custom interceptor not handling error conditions properly.
I have a function which creates a deferred object. On fail I'm calling a fallback function, which in turn creates and returns it's own deferred/promise object. I would like to return the result of this fallback-deferred but I'm only able to return the error on my initial call.
Here is what I'm doing:
// method call
init.fetchConfigurationFile(
storage,
"gadgets",
gadget.getAttribute("data-gadget-id"),
pointer
).then(function(fragment) {
console.log("gotcha");
console.log(fragment);
}).fail(function(error_should_be_fragment) {
console.log("gotcha not");
console.log(error_should_be_fragment);
});
My fetchConfiguration call tries to load from localstorage and falls back to loading from file if the document/attachment I need is not in localstorage.
init.fetchConfigurationFile = function (storage, file, attachment, run) {
return storage.getAttachment({"_id": file, "_attachment": attachment})
.then(function (response) {
return jIO.util.readBlobAsText(response.data);
})
.then(function (answer) {
return run(JSON.parse(answer.target.result))
})
.fail(function (error) {
// PROBLEM
console.log(error);
if (error.status === 404 && error.id === file) {
return init.getFromDisk(storage, file, attachment, run);
}
});
};
My problem is I can catch the 404 allright, but instead of returning the error object, I would like to return the promise generated by init.getFromDisk.
Question:
Is it possible to return the result of my getFromDisk call in the error handler? If not, how would I have to structure my calls so that I'm always returning a promise to my first method call?
Thanks for help!
SOLUTION:
Thanks for the help! Fixed it like this:
init.fetchConfigurationFile(
storage,
"gadgets",
gadget.getAttribute("data-gadget-id"),
pointer
).always(function(fragment) {
console.log("gotcha");
console.log(fragment);
});
init.fetchConfigurationFile = function (storage, file, attachment, run) {
return storage.getAttachment({"_id": file, "_attachment": attachment})
.then(function (response) {
return jIO.util.readBlobAsText(response.data);
})
.then(
function (answer) {
return run(JSON.parse(answer.target.result));
},
function (error) {
if (error.status === 404 && error.id === file) {
return init.getFromDisk(storage, file, attachment, run);
}
}
);
};
.fail() always returns the original promise.
You should call then() with a failure callback to allow chaining:
.then(undefined, function(error) {
return ...;
});
Before jQuery 1.8, use .pipe() instead.