Here's my code:
async [types.GET_DATA]({commit, state}, data) {
try {
const res = await axios.post('/login', {
email: data.email,
password: data.password,
});
console.log(res)
} catch(e) {
if(e.response) {
console.log(e.response)
}
}
}
So, I return 400 Bad Request whenever user sends empty fields. What axios does is throws the error along with the error response. What I need to do is remove that console error message and only get the error response.
How can I do it?
It is actually impossible to do with JavaScript. This is due to security concerns and a potential for a script to hide its activity from the user.
The best you can do is hide them from only your console.
If there is an error you can catch it like this:
axios.get("https://google.com").then(response => {
console.log("Done");
}).catch(err => {
console.log("Error");
})
async [types.GET_DATA]({commit, state}, data) {
try {
const res = await axios.post('/login', {
email: data.email,
password: data.password
});
console.log(res)
} catch(err) {
console.log(err)
}
}
Related
This may seem stupid, but I'm trying to get the error data when a request fails in Axios.
axios
.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log(error); //Logs a string: Error: Request failed with status code 404
});
Instead of the string, is it possible to get an object with perhaps the status code and content? For example:
Object = {status: 404, reason: 'Not found', body: '404 Not found'}
What you see is the string returned by the toString method of the error object. (error is not a string.)
If a response has been received from the server, the error object will contain the response property:
axios.get('/foo')
.catch(function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}
});
With TypeScript, it is easy to find what you want with the right type.
This makes everything easier because you can get all the properties of the type with autocomplete, so you can know the proper structure of your response and error.
import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
.then((response: AxiosResponse) => {
// Handle response
})
.catch((reason: AxiosError) => {
if (reason.response!.status === 400) {
// Handle 400
} else {
// Handle else
}
console.log(reason.message)
})
Also, you can pass a parameter to both types to tell what are you expecting inside response.data like so:
import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
.then((response: AxiosResponse<{user:{name:string}}>) => {
// Handle response
})
.catch((reason: AxiosError<{additionalInfo:string}>) => {
if (reason.response!.status === 400) {
// Handle 400
} else {
// Handle else
}
console.log(reason.message)
})
As #Nick said, the results you see when you console.log a JavaScript Error object depend on the exact implementation of console.log, which varies and (imo) makes checking errors incredibly annoying.
If you'd like to see the full Error object and all the information it carries bypassing the toString() method, you could just use JSON.stringify:
axios.get('/foo')
.catch(function (error) {
console.log(JSON.stringify(error))
});
There is a new option called validateStatus in request config. You can use it to specify to not throw exceptions if status < 100 or status > 300 (default behavior). Example:
const {status} = axios.get('foo.example', {validateStatus: () => true})
You can use the spread operator (...) to force it into a new object like this:
axios.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log({...error})
})
Be aware: this will not be an instance of Error.
I am using this interceptors to get the error response.
const HttpClient = axios.create({
baseURL: env.baseUrl,
});
HttpClient.interceptors.response.use((response) => {
return response;
}, (error) => {
return Promise.resolve({ error });
});
In order to get the http status code returned from the server, you can add validateStatus: status => true to axios options:
axios({
method: 'POST',
url: 'http://localhost:3001/users/login',
data: { username, password },
validateStatus: () => true
}).then(res => {
console.log(res.status);
});
This way, every http response resolves the promise returned from axios.
https://github.com/axios/axios#handling-errors
Whole error can only be shown using error.response like that :
axios.get('url').catch((error) => {
if (error.response) {
console.log(error.response);
}
});
const handleSubmit = (e) => {
e.preventDefault();
// console.log(name);
setLoading(true);
createCategory({ name }, user.token)
.then((res) => {
// console.log("res",res);
setLoading(false);
setName("");
toast.success(`"${res.data.name}" is created`);
loadCategories();
})
.catch((err) => {
console.log(err);
setLoading(false);
if (err.response.status === 400) toast.error(err.response.data);//explained in GD
});
};
See the console log then you will understand clearly
With Axios
post('/stores', body).then((res) => {
notifyInfo("Store Created Successfully")
GetStore()
}).catch(function (error) {
if (error.status === 409) {
notifyError("Duplicate Location ID, Please Add another one")
} else {
notifyError(error.data.detail)
}
})
It's indeed pretty weird that fetching only error does not return an object. While returning error.response gives you access to most feedback stuff you need.
I ended up using this:
axios.get(...).catch( error => { return Promise.reject(error.response.data.error); });
Which gives strictly the stuff I need: status code (404) and the text-message of the error.
Axios. get('foo.example')
.then((response) => {})
.catch((error) => {
if(error. response){
console.log(error. response. data)
console.log(error. response. status);
}
})
This is a known bug, try to use "axios": "0.13.1"
https://github.com/mzabriskie/axios/issues/378
I had the same problem so I ended up using "axios": "0.12.0". It works fine for me.
You can put the error into an object and log the object, like this:
axios.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log({error}) // this will log an empty object with an error property
});
It's my code: Work for me
var jsonData = request.body;
var jsonParsed = JSON.parse(JSON.stringify(jsonData));
// message_body = {
// "phone": "5511995001920",
// "body": "WhatsApp API on chat-api.com works good"
// }
axios.post(whatsapp_url, jsonParsed,validateStatus = true)
.then((res) => {
// console.log(`statusCode: ${res.statusCode}`)
console.log(res.data)
console.log(res.status);
// var jsonData = res.body;
// var jsonParsed = JSON.parse(JSON.stringify(jsonData));
response.json("ok")
})
.catch((error) => {
console.error(error)
response.json("error")
})
I am currently using the firebase functions to call the following doc from the database:
let token, userId;
db.doc(`/users/${newAccount.username}`)
.get()
.then((doc) => {
if (doc.exists === false) {
return firebase.auth().createUserWithEmailAndPassword(newAccount.email, newAccount.password).catch(err => console.error(err));
} else {
res.status(400).json({ username: 'this username is already taken' });
}
})
.then(data => {
userId = data.user.uid;
return data.user.getIdToken();
})
.then((idToken) => {
token = idToken;
const userCredentials = {
username: newAccount.username,
email: newAccount.email,
created: new Date().toISOString(),
userId
};
return db.doc(`/users/${newAccount.username}`).set(userCredentials);
})
.then(() => {
return res.status(201).json({ token });
})
.catch((err) => {
console.error(err);
if (err.code === 'auth/email-already-in-use') {
return res.status(400).json({ email: 'Email is already is use' });
} else {
return res.status(500).json({ general: 'Something went wrong, please try again' });
}
});
The code runs fine but there is a logged error, if the doc exists in the database:
TypeError: Cannot read property 'user' of undefined
I presume the promise is still running and I am a bit stuck on how to end it?
Any help would be grateful. Thanks.
Your second then callback is going to get invoked in all situations. Sending the 400 response in the first callback isn't actually going to stop the promise from propagating to all of the following then callbacks.
If you want to stop the chain of then callbacks from executing, you should instead throw an error to get picked up by a catch down the chain, skipping all the then.
I've been facing with problem with redis and async await.
I have old redis.get with callback:
redis.get(token, async (error, result) => {
if (error) {
return res.status(404).json({ msg: 'Confirm token is invalid.' });
}
if (result === null) {
return res.status(400).json({ msg: 'Confirm token is expired.' });
}
})
But i will want to refactor him to async/await
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
const result = async redis.asyncGet(token)
I successfully get the result, BUT how can i get the error ?
Thanks
Having your code, you just need to surround the redis call using async/await syntax in a try/catch statement:
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
try {
const result = redis.get(token);
} catch (e) {
return res.status(400).send({ msg: 'Confirm token is expired.' })
}
My problem is the next:
//express server
app.post('/register', (req, res) => {
const {
password,
passwordConfirm
} = req.body;
if (password === passwordConfirm) {
//...
} else {
res.status(400).json("Passwords aren't matching")
}
})
//react function
onSubmitSignIn = () => {
const { password, passwordConfirm } = this.state;
let data = new FormData();
data.append('password', password);
data.append('passwordConfirm', passwordConfirm);
fetch('http://localhost:3001/register', {
method: 'post',
body: data
})
.then(response => response.json())
.then(user => {
//logs error message here
console.log(user)
})
//but I want to catch it here, and set the message to the state
.catch(alert => this.setState({alert}))
}
When I send the status code, and the message from express as the response, the front-end obviously recognize it as the response, that's why it logs the message to the console as "user". But how to send error which goes to the catch function?
fetch will really only error if it for some reason can't reason the API. In other words it will error on network errors. It will not explicitly error for non 2XX status codes.
You need to check the ok property as described here:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful
https://developer.mozilla.org/en-US/docs/Web/API/Response/ok
--
fetch('http://localhost:3001/register', {
method: 'post',
body: data
})
.then(response => {
if (!response.ok) {
throw new Error('my api returned an error')
}
return response.json()
})
.then(user => {
console.log(user)
})
.catch(alert => this.setState({alert}))
The problem is, that fetch is not recognizing the HTTP errors as Promise rejections.
The Promise returned from fetch() won't reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally, and it will only reject on network failure or if anything prevented the request from completing.
(Source)
You can checkout the linked source of the fetch repo which also states a suggestion for handling HTTP error statuses.
What if you throw an error :
app.get("/", function (req, res) {
throw new Error("BROKEN"); // Express will catch this on its own.
});
And then catch this error in the front end ?
See here for reference
EDIT
Maybe should you return the error with return next() so that the rest of the code is not processed in the server method :
app.get("/", function (req, res) {
return next(new Error('BROKEN'));
});
//express server
app.post('/register', (req, res) => {
try {
const {
password,
passwordConfirm
} = req.body;
if (password === passwordConfirm) {
//...
} else {
res.status(400).json("Passwords aren't matching")
}
} catch (error) {
res.status(500).send(error);
}
})
//react function
onSubmitSignIn = () => {
const {
password,
passwordConfirm
} = this.state;
let data = new FormData();
data.append('password', password);
data.append('passwordConfirm', passwordConfirm);
fetch('http://localhost:3001/register', {
method: 'post',
body: data
})
.then(response => response.json())
.then(user => {
//logs error message here
console.log(user)
})
//but I want to catch it here, and set the message to the state
.catch(alert => this.setState({
alert
}))
}
Right now I want to save user token after the user login successful.
Here is my code:
onPress(){
return axios.post('https://api.example.net/v1/user/auth/login', {
email: this.state.email,
password: this.state.password,
}, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then((response) => {
AsyncStorage.setItem('token', response.data.login._cxz, () => {
console.log('success');
});
this.props.navigator.immediatelyResetRouteStack([{name: 'tweets'}]);
})
.catch((error) => {
this.setState({errorMessage: error.response.data.message});
});
}
I already make sure that response.data.login._cxz has a value.
Right until here is working. the login will redirect me to tweets route.
On my tweets.js:
constructor(props){
super(props);
this.state({token : ''});
}
componentWillMount() {
AsyncStorage.getItem('token', (err, value) => {
console.log(value);
})
}
I just simple console.log it to view if the token is saved or not.
But everytime login is done (the success log is appear). I always got this error when enter my tweets:
Any solution?
Thanks.
What is most likely happening is that the then callback is throwing an error at navigator.immediatelyResetRouteStack:
.then((response) => {
AsyncStorage.setItem('token', response.data.login._cxz, () => {
console.log('success');
});
this.props.navigator.immediatelyResetRouteStack([{name: 'tweets'}]);
})
.catch((error) => {
this.setState({errorMessage: error.response.data.message});
});
The error is then caught in the catch block, but because the error is a normal JavaScript Error and not an axios error, it does not have response property, and therefore trying to access error.response.data causes the undefined error.
The easy way to detect the kind of error is to duck-type it: If the error has a response, then it's an axios error, otherwise another error:
.catch((error) => {
if (error.response && error.response.data) {
this.setState({errorMessage: error.response.data.message});
} else {
this.setState({errorMessage: error.message});
}
});
The error caused by immediatelyResetRouteStack is probably coming from the React render pass that is synchronously executed on the same call stack. Once you fix the broken .catch you'll see what the error message is, but a good guess for a culprit in your limited code sample is:
this.state({token : ''});
Which should be an property assignment, instead of a method call:
this.state = {token : ''};