Is there a way to access my response error message? - javascript

Ok So i am trying to display my backend error messages in the front end, so I have it setup to send the response with the error code and a message and then in my action I am setting a state in my React component which I will then use to display the error message, so far I can get to display the error code but that is no use to most users so I would like to access the message I send with the code! So I want it to say user already exists or passwords do not match rather than Error: Request failed with status code 400
my action
export const signup = (form, router, setError) => async (dispatch) => {
const changeError = (error) => {
setError(error);
};
try {
const { data } = await api.signup(form);
dispatch({ type: AUTH, data });
router.push("/");
} catch (error) {
console.log(error);
changeError(error);
}
};
my node signup
export const signup = async (req, res) => {
const { email, password, confirmPassword, firstName, lastName } = req.body;
try {
const existingUser = await user.findOne({ email });
if (existingUser)
return res.status(400).json({ message: "User already exists." });
if (password != confirmPassword)
return res.status(400).json({ message: "Passwords do not match." });
const hashedPassword = await bcrypt.hash(password, 12);
const result = await user.create({
email,
password: hashedPassword,
name: `${firstName} ${lastName}`,
});
const token = jwt.sign(
{ email: result.email, id: result._id },
process.env.JWT_KEY,
{
expiresIn: "1h",
}
);
res.status(200).json({ result, token });
} catch (error) {
res.status(500).json({ message: "Something went wrong." });
}
};

After little search on Google, if you are using Axios as your api, the path to the error message is:
error.response.data.message
else, have you tried somthing like this?
error.data.message
or
error.message

as Guy said, slightly before I found the answer myself I set the error to error.response.data.message
so now I can set my error in the front end to display the message
and yea sorry was using axios, I'll know better for next time to mention that!
export const signup = (form, router, setError) => async (dispatch) => {
const changeError = (error) => {
setError(error);
};
try {
const { data } = await api.signup(form);
dispatch({ type: AUTH, data });
router.push("/");
} catch (error) {
console.log(error);
changeError(error.response.data.message);
}
};

Related

my homepage wont render using my google oauth

This is the error that I get:
"You have created a new client application that use…i/web/guides/gis-migration) for more information."
here are my codes on server, the statement inside console.log doesnt even show:
static async googleLogin(req, res, next) {
try {
console.log("masuk google login server")
const { id_token } = req.body
const client = new OAuth2Client(process.env.GOOGLE_CLIENT_ID)
const ticket = await client.verifyIdToken({
idToken: id_token,
audience: process.env.GOOGLE_CLIENT_ID
});
const payload = ticket.getPayload()
const email = payload.email
let password = email.toString().split('#')
password = password[0]
let user = await User.findOne({ where: { email } })
if (!user) {
let newUser = { email, password }
let createUser = await User.create(newUser)
const payload = {
id: createUser.id,
email: createUser.email
}
const access_token = generateToken(payload)
return res.status(201).json({ access_token })
} else {
const payload = {
id: user.id,
email: user.email
}
const access_token = generateToken(payload)
return res.status(200).json({ access_token })
}
} catch (err) {
console.log(err)
return next(err)
}
}
the console.log in my client also doesnt show
function onSignIn(googleUser) {
console.log("masuk client oauth")
$.ajax({
method: "POST",
url: `${baseUrl}/users/google-login`,
data: {
id_token: googleUser.getAuthResponse().id_token
}
})
.done((response) => {
console.log(response, "client response")
localStorage.setItem("access_token", response.access_token)
checkLocalStorage();
})
.fail((err) => {
console.log(err, "error client");
})
.always(() => {
authentication()
})
}
i tried deleting cache and run my app again, recreate a new project on google api (which genereated new ID). they didnt work

Not returning an error after failed post request - axios, express, node.js

I am trying to implement the validation of password change and the issue I have is that I am not getting errorMessage back from the server in case of an error. I have managed to get it work and send back response after the password was updated. Also, I can console.log the error message on the back end but it's not returning an object with errorMessage to the front end.
if (!currentPassword) {
console.log("no current password");
return res
.status(400)
.json({ errorMessage: "Please confirm your current password" });
}
On the front code looks like this:
handleSubmit = (event) => {
event.preventDefault();
const authorization = localStorage.getItem("accessToken");
axios
.put(
`${process.env.REACT_APP_SERVER_URL}/settings/password`,
this.state.user,
{
headers: {
authorization,
},
}
)
.then((res) => {
if (res.errorMessage) {
console.log(res, "Unsuccessful password updated");
} else {
console.log("updating - res:", res);
this.setState({
user: res.data,
});
}
})
.catch((err) => {
console.log(err, "ERROR");
});
};
Everytime there is an error, I am not consol login the actual erroMessage but it is being catched in catch. What is the cause of that?
Thanks
Not a direct res its available under res.data.
Response schema of axios
use
if (res.data.errorMessage) {
instead of
if (res.errorMessage) {
For better understanding you need to console.log(res). Then you could understand the structure of the response
router.put("/password", isLoggedIn, (req, res, next) => {
const { currentPassword, newPassword, newPasswordConfirm } = req.body;
User.findById(req.user._id)
.then((user) => {
bcrypt.compare(currentPassword, user.password).then((isSamePassword) => {
if (!isSamePassword) {
console.log(
"Incorrect current password. To change your password try again!"
);
return res.status(400).json({
errorMessage:
"Incorrect current password. To change your password try again!",
});
}
return bcrypt
.genSalt(saltRounds)
.then((salt) => bcrypt.hash(newPassword, salt))
.then((hashedPassword) => {
User.findByIdAndUpdate(
req.user._id,
{ password: hashedPassword },
{ new: true }
)
.then((user) => {
console.log("user's password successfully changed");
res.status(200).json(user);
})
.catch((err) => {
res.status(500).json({ errorMessage: err.message });
});
})
.catch((err) => {
res.status(500).json({ errorMessage: err.message });
});
});
})
.catch((err) => {
console.log(err);
res.status(500).json({ errorMessage: err.message });
});
});

What is the problem in the nodejs controller function?

exports.signupController = async (req, res) => {
const { phone, password } = req.body;
try {
const user = await User.findOne({ phone }).exec()
if (user) {
return res.status(400).json({
errorMessage: 'Phone Number already exists',
});
}
const newUser = new User();
newUser.phone = phone;
const salt = await bcrypt.genSalt(10);
newUser.password = await bcrypt.hash(password, salt);
await newUser.save();
return res.status(200).json({
successMessage: 'Registration success. Please login',
});
} catch (err) {
console.log('signupController error: ', err);
res.status(500).json({
errorMessage: 'Server error',
});
}};
**I upload a node application in shared hosting! **
*But an error was showing in this controller function. All the time the catch block is running on the json. The error is unhandled promise rejection. *
signup(data)
.then((response) => {
console.log('Axios signup success: ', response);
setFormData({
phone: '',
password: '',
password2: '',
loading: false,
successMsg: response.data.successMessage,
});
history.push('/signin');
})
.catch((err) => {
console.log('Axios signup error: ', err);
setFormData({
...formData,
loading: false,
errorMsg: err.response.data.errorMessage,
});
});
this is react front end event handler
import axios from 'axios';
export const signup = async (data) => {
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const response = await axios.post('/api/auth/signup', data, config);
return response;
};
the signup api function
Mongoose queries are not promises. They have a .then() function for co and async/await as a convenience. If you need a fully-fledged promise, use the .exec() function. for example:
const query = Band.findOne({name: "Guns N' Roses"});
assert.ok(!(query instanceof Promise));
// A query is not a fully-fledged promise, but it does have a `.then()`.
query.then(function (doc) {
// use doc
});
// `.exec()` gives you a fully-fledged promise
const promise = query.exec();
assert.ok(promise instanceof Promise);
promise.then(function (doc) {
// use doc
});
If you are using exec() on your findOne query you should use:
exports.signupController = async (req, res) => {
const { phone, password } = req.body;
try {
const user = await User.findOne({ phone }).exec();
/// just a pseudo code
user.then('do your things').catch( 'log error')
const newUser = new User();
newUser.phone = phone;
const salt = await bcrypt.genSalt(10);
newUser.password = await bcrypt.hash(password, salt);
await newUser.save();
return res.status(200).json({
successMessage: 'Registration success. Please login',
});
} catch (err) {
console.log('signupController error: ', err);
res.status(500).json({
errorMessage: 'Server error',
});
}};
for more details check this out: https://mongoosejs.com/docs/promises.html#should-you-use-exec-with-await?

redux not catching errors

So whenever the app is loaded it should check for user Auth using the loadUser(), the problem I'm having is that if there is no token in localStorage, the server won't return any errors(when its suppose to). I looked at the code for auth(backend), and it returns a status meassage when no token received, I was wondering is it because no token isn't a type of error, that's way the server didn't send an error response?
Below are the code snippets:
auth.js(backend)
const jwt = require("jsonwebtoken");
const config = require("config");
module.exports = function (req, res, next) {
//get token from header
const token = req.header("x-auth-token");
// check if not token
if (!token) {
return res.status(401).json({ msg: "no token, auth denied" });
}
//verify token
try {
const decoded = jwt.verify(token, config.get("jwtSecret"));
req.user = decoded.user;
next();
} catch (err) {
res.status(401).json({
msg: "token isnt valid",
});
}
};
App.js
const App = () => {
useEffect(() => {
if (localStorage.token) {
setAuthToken(localStorage.token);
store.dispatch(loadUser());
}
}, []);
auth.js Redux
export const loadUser = () => async (dispatch) => {
console.log("from auth.js");
if (localStorage.token) {
setAuthToken(localStorage.token);
}
try {
const res = await axios.get("/api/auth");
console.log("inside auth.js get auth route");
dispatch({
type: USER_LOADED,
payload: res.data,
});
} catch (err) {
console.log("error from auth.js");
dispatch({
type: AUTH_ERROR,
});
}
};
Basically the code inside catch(err) { //code }
is not executed.
Silly of me, added else condition into App.js solved the issue.

Issue in sending error message from backend(nodejs) to frontend(reactjs)

I am implementing a login feature, so when the user enter wrong credentials, I am passing an error 'Wrong Credentials' to the frontend, but at frontend I receive a different error message.
this is the relevant backend code
exports.loginUser = async (req, res) => {
try{
const loggedinUser = await userService.loginUser(res, req.body);
if(loggedinUser.error){
throw new Error(loggedinUser.error); //loggedinUser.error is 'Wrong credentials'
}
const tokenPayload = {
userName: loggedinUser[0].name,
email: loggedinUser[0].email
}
const token = jwt.sign(tokenPayload, keys.JWT.TOKEN_SECRET, {expiresIn: '60m'} );
const tokenData = {
token: token,
name: tokenPayload.userName,
email: tokenPayload.email
}
const redirectURL = url.format({
pathname: '/dashboard/buzz',
query: tokenData
});
res.send({redirectTo: redirectURL});
} catch(err){
console.log(err); //prints wrong credentials
res.status(400).json(err);
}
}
this is the relevant frontend code
const loginHandler = ( event ) => {
event.preventDefault();
setShowValidationMessage(true);
const loginDetails = {
email: loginForm.email.value,
password: loginForm.password.value
}
if(formIsValid){
axios.post('http://localhost:5000/login', loginDetails)
.then(res=>setRedirectURL(res.data.redirectTo))
.catch(err=>{
console.log(err.message);// prints Request failed with status code 400
});
}
}

Categories