Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix error handling on session restore #1859

Merged
merged 9 commits into from
Apr 30, 2018

Conversation

dbkr
Copy link
Member

@dbkr dbkr commented Apr 26, 2018

Fix a number of failures that meant the excellent error handling
we had for failing to restore a session didn't work.

  1. .catch on the promise rather than try/catch: it's async
  2. Explicit cancel method in SessionRestoreErrorDialog that invokes
    onFinished with false because even with the catch fixed, this
    was getting the event as its first arg which is truthy, so
    clicking cancel still deleted your data.
  3. DialogButtons: Don't pass onCancel straight into the button event
    handler as this leaks the MouseEvent through as an argument.
    Nothing is using it and it exacerbates failures like this
    because there are surprise arguments.

Lots of re-indenting has gone on too: reading commits individually may be useful.

Fixes element-hq/element-web#6616

Fix a number of failures that meant the excellent error handling
we had for failing to restore a session didn't work.

1. .catch on the promise rather than try/catch: it's async
2. Explicit cancel method in SessionRestoreErrorDialog that invokes
   onFinished with `false` because even with the catch fixed, this
   was getting the event as its first arg which is truthy, so
   clicking cancel still deleted your data.
3. DialogButtons: Don't pass onCancel straight into the button event
   handler as this leaks the MouseEvent through as an argument.
   Nothing is using it and it exacerbates failures like this
   because there are surprise arguments.

Fixes element-hq/element-web#6616
@dbkr
Copy link
Member Author

dbkr commented Apr 26, 2018

Actually sorry, this error handling should be moved up a level or two as there are classes of errors that still dump you at a login screen.

@dbkr dbkr assigned dbkr and unassigned lukebarnard1 Apr 26, 2018
Everywhere else, onFinished takes a boolean indicating whether the
dialog was confirmed on cancelled, and had function that were
expecting this variable and getting undefined.
The user might (probably does) have a session even if we haven't actually tried
to load it yet, so wrap the whole loadSession code in the error handler we were
using for restoring sessions so we gracefully handle exceptions that happen
before trying to restore sessions too.

Remove the catch in MatrixChat that sent you to the login screen.  This is
never the right way to handle an error condition: we should only display the
login screen if we successfully determined that the user has no session, or
they explicitly chose to blow their sessions away.
@dbkr dbkr assigned lukebarnard1 and unassigned dbkr Apr 27, 2018
@dbkr
Copy link
Member Author

dbkr commented Apr 27, 2018

OK, ready again now.

@lukebarnard1
Copy link
Contributor

Tests appear to be legitimately failing

@dbkr
Copy link
Member Author

dbkr commented Apr 27, 2018

Hurrah for legitimate test failures!

@lukebarnard1
Copy link
Contributor

Apparently eslint is sad.

@lukebarnard1 lukebarnard1 assigned dbkr and unassigned lukebarnard1 Apr 27, 2018
@dbkr
Copy link
Member Author

dbkr commented Apr 27, 2018

right, actually green & ticky now

@lukebarnard1 lukebarnard1 assigned lukebarnard1 and unassigned dbkr Apr 27, 2018
Copy link
Contributor

@lukebarnard1 lukebarnard1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from these issues, there seems to be confusion around onFinished being used differently by different components. We should probably not do that.

src/Lifecycle.js Outdated
guest: true,
}, true).then(() => true);
}
return Promise.resolve().then(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite difficult to read, any chance of making loadSession async?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, probably better. Done, plus the restore function.

homeserverUrl: guestHsUrl,
identityServerUrl: guestIsUrl,
guest: true,
}, true).then(() => true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering whether we should really be returning true/false instead of throwing exceptions. Do you have thoughts on this @dbkr?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the logic here is: true == logged in, false == there was no session, exception == it's all screwed, so they have distinct useful meanings which are now hopefully clearer in async / await form rather than promise chains.

src/Lifecycle.js Outdated
// legacy key name
isGuest = localStorage.getItem("matrix-is-guest") === "true";
}
return Promise.resolve().then(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm finding it quite strange that the whole thing is wrapped in a resolved promise. Should this be an async function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}).then((loadedSession) => {
if (!loadedSession) {
// fall back to showing the login screen
dis.dispatch({action: "start_login"});
}
});
// Note we don't catch errors from this: we catch everything within
// loadSession as there's logic there to ask the user if they want
// to try logging out.
}).done();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed we do not

@@ -36,6 +36,9 @@ export default React.createClass({

propTypes: {
// onFinished callback to call when Escape is pressed
// Take a boolean which is true is the dialog was dismissed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"is true is"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

@@ -36,6 +36,9 @@ export default React.createClass({

propTypes: {
// onFinished callback to call when Escape is pressed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this now false? What about all the dialogs that depend on it being true?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They were all either taking no args or relying on cancel == called with false

@@ -36,6 +36,9 @@ export default React.createClass({

propTypes: {
// onFinished callback to call when Escape is pressed
// Take a boolean which is true is the dialog was dismissed
// with a positive / confirm action or false if it was
// cancelled (from BaseDialog, this is always false).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, onFinished is never called with a truthy value, so the next comment is not true.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in the 'this is always false' comment? Yeah, that was what I meant. Have tried to be clearer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, well if the BaseDialog has no way to provide an affirmative response, this makes sense. Thanks for clarifying.

@lukebarnard1 lukebarnard1 assigned dbkr and unassigned lukebarnard1 Apr 27, 2018
@dbkr dbkr assigned lukebarnard1 and unassigned dbkr Apr 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

don't show the login page if an exception occurs insetLoggedIn or similar
2 participants