问题
I have a two step forgot password process. I'm rendering two forms using React. The first form takes an email address and upon submit, successfully executes my resetPassword() function. The function successfully sends the user a security code via email. This part works fine.
Then, the next form is rendered which takes in the security code and a password (password and confirmPassword - they must be the same, obviously). Then, upon submit of this form, it executes the confirmPassword() function. This function however enters the catch block and throws the following exception:
exception:TypeError: Converting circular structure to JSON
As I'm very new to Node.js, I'm not sure where this is coming from, or how to debug it. Any suggestions?
My two functions are below. Again, it's the second function that is failing. Also, I confirmed in Cognito after the exception is thrown, and the user status is still in Enabled / RESET_REQUIRED
status.
Note: I've marked the code with (// ERROR IS HAPPENING HERE) - this is the section of code where the exception is getting thrown. See the very bottom of the code below.
resetPassword() {
const userPool = new CognitoUserPool({
UserPoolId: config.cognito.USER_POOL_ID,
ClientId: config.cognito.APP_CLIENT_ID
});
// setup cognitoUser first
let cognitoUser = new CognitoUser({
Username: this.state.email,
Pool: userPool
});
// initiate the forgotPassword flow, this part sends a security code to the email address given.
const promise = new Promise((resolve, reject) => {
cognitoUser.forgotPassword({
onSuccess: function(result) {
console.log(util.inspect(result, { showHidden: true, depth: null }));
// var str = JSON.stringify(result, null, 4);
// console.log("success, result data: " + str);
resolve(result);
},
onFailure: function(err) {
console.log(util.inspect(err, { showHidden: true, depth: null }));
// var str = JSON.stringify(err, null, 4);
// console.log("error, e data: " + str);
reject(err);
},
undefined
});
});
return promise;
}
confirmPassword(username, verificationCode, newPassword) {
const userPool = new CognitoUserPool({
UserPoolId: config.cognito.USER_POOL_ID,
ClientId: config.cognito.APP_CLIENT_ID
});
// setup cognitoUser first
let cognitoUser = new CognitoUser({
Username: this.state.email,
Pool: userPool
});
const promise = new Promise((resolve, reject) => {
cognitoUser.confirmPassword(verificationCode, newPassword, {
onFailure: (err) => {
console.log("onFailure:" + err);
reject(err);
},
onSuccess: (res) => {
console.log("onSuccess:");
resolve();
},
undefined
});
});
return promise;
}
handleSubmit = async event => {
event.preventDefault();
this.setState({ isLoading: true, emailSubmitted: true });
try {
let newUser = await this.resetPassword();
console.log(util.inspect(newUser, { showHidden: true, depth: null }));
// var str = JSON.stringify(newUser, null, 4);
// console.log("newUser:" + str);
} catch (e) {
console.log(util.inspect(e, { showHidden: true, depth: null }));
// var str = JSON.stringify(e, null, 4);
// console.log("Exception:" + str);
}
this.setState({ isLoading: false });
}
handleConfirmationSubmit = async event => {
event.preventDefault();
this.setState({ isLoading: true });
try {
let confirm_result = await this.confirmPassword(this.state.securityCode, this.state.password, this);
console.log(util.inspect(confirm_result, { showHidden: true, depth: null }));
// console.log("confirm_result:" + confirm_result);
} catch (e) {
// console.log(util.inspect(e));
// console.log("exception:" + e);
// ERROR IS HAPPENING HERE.
console.log(util.inspect(e, { showHidden: true, depth: null }));
console.log(new Error().stack);
/* Stack trace shows:
Error
at ForgotPassword._callee2$ (ForgotPassword.js:154)
at tryCatch (runtime.js:62)
at Generator.invoke [as _invoke] (runtime.js:296)
at Generator.prototype.(anonymous function) [as throw] (http://localhost:3000/static/js/bundle.js:61658:21)
at step (ForgotPassword.css?776b:26)
at ForgotPassword.css?776b:26
*/
this.setState({ isLoading: false });
}
}
回答1:
I remember this circular JSON error
happening when I was trying to modify the Cognito User data across two different contexts while the underlying dataset is the same. In my use case, I was modifying the dataset once at the browser and also at the lambda function. I don't remember Cognito giving me back an intuitive error message to solve this. When I started operating on different data sets at browser vs. lambda callback, this went away. Maybe you could try doing as below and see if that works -
const userPool = new CognitoUserPool({
UserPoolId: config.cognito.USER_POOL_ID,
ClientId: config.cognito.APP_CLIENT_ID
});
// setup cognitoUser first
let cognitoUser = new CognitoUser({
Username: this.state.email,
Pool: userPool
});
resetPassword() {
// initiate the forgotPassword flow, this part sends a security code to the email address given.
const promise = new Promise((resolve, reject) => {
cognitoUser.forgotPassword({
onSuccess: function(result) {
console.log(util.inspect(result, { showHidden: true, depth: null }));
// var str = JSON.stringify(result, null, 4);
// console.log("success, result data: " + str);
resolve(result);
},
onFailure: function(err) {
console.log(util.inspect(err, { showHidden: true, depth: null }));
// var str = JSON.stringify(err, null, 4);
// console.log("error, e data: " + str);
reject(err);
},
undefined
});
});
return promise;
}
confirmPassword(username, verificationCode, newPassword) {
const promise = new Promise((resolve, reject) => {
cognitoUser.confirmPassword(verificationCode, newPassword, {
onFailure: (err) => {
console.log("onFailure:" + err);
reject(err);
},
onSuccess: (res) => {
console.log("onSuccess:");
resolve();
},
undefined
});
});
return promise;
}
来源:https://stackoverflow.com/questions/49417859/amazon-cognito-confirmpassword-fails-with-typeerror-converting-circular-struct