Merge pull request #15845 from JoVictorNunes/improved-error-screen-messages-backport
[2.5] improvement: error screen messages and logs
This commit is contained in:
commit
8968f1c91a
@ -11,6 +11,7 @@ import userActivitySign from './methods/userActivitySign';
|
||||
import userLeftMeeting from './methods/userLeftMeeting';
|
||||
import changePin from './methods/changePin';
|
||||
import setRandomUser from './methods/setRandomUser';
|
||||
import setExitReason from './methods/setExitReason';
|
||||
|
||||
Meteor.methods({
|
||||
setEmojiStatus,
|
||||
@ -25,4 +26,5 @@ Meteor.methods({
|
||||
userLeftMeeting,
|
||||
changePin,
|
||||
setRandomUser,
|
||||
setExitReason,
|
||||
});
|
||||
|
@ -0,0 +1,21 @@
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { extractCredentials } from '/imports/api/common/server/helpers';
|
||||
import setUserExitReason from '/imports/api/users/server/modifiers/setUserExitReason';
|
||||
|
||||
export default function setExitReason(reason) {
|
||||
try {
|
||||
const { meetingId, requesterUserId } = extractCredentials(this.userId);
|
||||
|
||||
// Unauthenticated user, just ignore and go ahead.
|
||||
if (!meetingId || !requesterUserId) return;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(reason, String);
|
||||
|
||||
setUserExitReason(meetingId, requesterUserId, reason);
|
||||
} catch (err) {
|
||||
Logger.error(`Exception while invoking method setExitReason ${err.stack}`);
|
||||
}
|
||||
};
|
@ -45,7 +45,20 @@ export default function userLeaving(meetingId, userId, connectionId) {
|
||||
|
||||
ClientConnections.removeClientConnection(`${meetingId}--${userId}`, connectionId);
|
||||
|
||||
Logger.info(`User '${userId}' is leaving meeting '${meetingId}'`);
|
||||
let reason;
|
||||
|
||||
if (user.loggedOut) {
|
||||
// User explicitly requested logout.
|
||||
reason = 'logout';
|
||||
} else if (user.exitReason) {
|
||||
// User didn't requested logout but exited graciously.
|
||||
reason = user.exitReason;
|
||||
} else {
|
||||
// User didn't exit graciously (disconnection).
|
||||
reason = 'disconnection';
|
||||
}
|
||||
|
||||
Logger.info(`User '${userId}' is leaving meeting '${meetingId}' reason=${reason}`);
|
||||
RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, userId, payload);
|
||||
} catch (err) {
|
||||
Logger.error(`Exception while invoking method userLeaving ${err.stack}`);
|
||||
|
@ -0,0 +1,25 @@
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Users from '/imports/api/users';
|
||||
|
||||
export default function setUserExitReason(meetingId, userId, reason) {
|
||||
const selector = {
|
||||
meetingId,
|
||||
userId,
|
||||
};
|
||||
|
||||
const modifier = {
|
||||
$set: {
|
||||
exitReason: reason,
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const numberAffected = Users.update(selector, modifier);
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Set exit reason userId=${userId} meeting=${meetingId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Setting user exit reason: ${err}`);
|
||||
}
|
||||
};
|
@ -26,6 +26,7 @@ import DebugWindow from '/imports/ui/components/debug-window/component';
|
||||
import { ACTIONS, PANELS } from '../../ui/components/layout/enums';
|
||||
import { isChatEnabled } from '/imports/ui/services/features';
|
||||
import MediaService from '/imports/ui/components/media/service';
|
||||
import { makeCall } from '/imports/ui/services/api';
|
||||
|
||||
const CHAT_CONFIG = Meteor.settings.public.chat;
|
||||
const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id;
|
||||
@ -319,6 +320,10 @@ class Base extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
static async setExitReason(reason) {
|
||||
return await makeCall('setExitReason', reason);
|
||||
}
|
||||
|
||||
renderByState() {
|
||||
const { updateLoadingState } = this;
|
||||
const stateControls = { updateLoadingState };
|
||||
@ -332,7 +337,6 @@ class Base extends Component {
|
||||
meetingEndedReason,
|
||||
meetingIsBreakout,
|
||||
subscriptionsReady,
|
||||
User,
|
||||
} = this.props;
|
||||
|
||||
if ((loading || !subscriptionsReady) && !meetingHasEnded && meetingExist) {
|
||||
@ -340,30 +344,39 @@ class Base extends Component {
|
||||
}
|
||||
|
||||
if (ejected) {
|
||||
return (<MeetingEnded code="403" ejectedReason={ejectedReason} />);
|
||||
return (
|
||||
<MeetingEnded
|
||||
code="403"
|
||||
ejectedReason={ejectedReason}
|
||||
callback={() => Base.setExitReason('ejected')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if ((meetingHasEnded || User?.loggedOut) && meetingIsBreakout) {
|
||||
window.close();
|
||||
if (meetingHasEnded && meetingIsBreakout) {
|
||||
Base.setExitReason('breakoutEnded').finally(() => {
|
||||
Meteor.disconnect();
|
||||
window.close();
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
if (((meetingHasEnded && !meetingIsBreakout)) || (codeError && User?.loggedOut)) {
|
||||
if (meetingHasEnded && !meetingIsBreakout) {
|
||||
return (
|
||||
<MeetingEnded
|
||||
code={codeError}
|
||||
endedReason={meetingEndedReason}
|
||||
ejectedReason={ejectedReason}
|
||||
callback={() => Base.setExitReason('meetingEnded')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (codeError && !meetingHasEnded) {
|
||||
// 680 is set for the codeError when the user requests a logout
|
||||
// 680 is set for the codeError when the user requests a logout.
|
||||
if (codeError !== '680') {
|
||||
return (<ErrorScreen code={codeError} />);
|
||||
return (<ErrorScreen code={codeError} callback={() => Base.setExitReason('error')} />);
|
||||
}
|
||||
return (<MeetingEnded code={codeError} />);
|
||||
return (<MeetingEnded code={codeError} callback={() => Base.setExitReason('logout')} />);
|
||||
}
|
||||
|
||||
return (<AppContainer {...this.props} baseControls={stateControls} />);
|
||||
@ -454,7 +467,7 @@ export default withTracker(() => {
|
||||
const connectionIdUpdateTime = User?.connectionIdUpdateTime;
|
||||
|
||||
if (currentConnectionId && currentConnectionId !== connectionID && connectionIdUpdateTime > connectionAuthTime) {
|
||||
Session.set('codeError', 403);
|
||||
Session.set('codeError', '409');
|
||||
Session.set('errorMessageDescription', 'joined_another_window_reason')
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,16 @@ export default injectIntl(withModalMounter(withTracker(({ intl, baseControls })
|
||||
setTimeout(() => {
|
||||
const queryCurrentUser = Users.find({ userId: Auth.userID, meetingId: Auth.meetingID });
|
||||
if (queryCurrentUser.count() === 0) {
|
||||
endMeeting(403, userData.ejectedReason || null);
|
||||
if (userData.ejected) {
|
||||
endMeeting('403', userData.ejectedReason);
|
||||
} else {
|
||||
// Either authentication process hasn't finished yet or user did authenticate but Users
|
||||
// collection is unsynchronized. In both cases user may be able to rejoin.
|
||||
const description = Auth.isAuthenticating || Auth.loggedIn
|
||||
? 'able_to_rejoin_user_disconnected_reason'
|
||||
: null;
|
||||
endMeeting('503', description);
|
||||
}
|
||||
}
|
||||
}, delayForReconnection);
|
||||
},
|
||||
|
@ -8,6 +8,9 @@ import logger from '/imports/startup/client/logger';
|
||||
import Styled from './styles';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
503: {
|
||||
id: 'app.error.503',
|
||||
},
|
||||
500: {
|
||||
id: 'app.error.500',
|
||||
defaultMessage: 'Oops, something went wrong',
|
||||
@ -15,6 +18,9 @@ const intlMessages = defineMessages({
|
||||
410: {
|
||||
id: 'app.error.410',
|
||||
},
|
||||
409: {
|
||||
id: 'app.error.409',
|
||||
},
|
||||
408: {
|
||||
id: 'app.error.408',
|
||||
},
|
||||
@ -55,6 +61,9 @@ const intlMessages = defineMessages({
|
||||
not_enough_permission_eject_reason: {
|
||||
id: 'app.meeting.logout.permissionEjectReason',
|
||||
},
|
||||
able_to_rejoin_user_disconnected_reason: {
|
||||
id: 'app.error.disconnected.rejoin',
|
||||
},
|
||||
});
|
||||
|
||||
const propTypes = {
|
||||
@ -65,15 +74,18 @@ const propTypes = {
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
code: 500,
|
||||
code: '500',
|
||||
callback: async () => {},
|
||||
};
|
||||
|
||||
class ErrorScreen extends PureComponent {
|
||||
componentDidMount() {
|
||||
const { code } = this.props;
|
||||
const log = code === 403 ? 'warn' : 'error';
|
||||
const { code, callback } = this.props;
|
||||
const log = code === '403' ? 'warn' : 'error';
|
||||
AudioManager.exitAudio();
|
||||
Meteor.disconnect();
|
||||
callback().finally(() => {
|
||||
Meteor.disconnect();
|
||||
});
|
||||
logger[log]({ logCode: 'startup_client_usercouldnotlogin_error' }, `User could not log in HTML5, hit ${code}`);
|
||||
}
|
||||
|
||||
@ -92,7 +104,7 @@ class ErrorScreen extends PureComponent {
|
||||
|
||||
let errorMessageDescription = Session.get('errorMessageDescription');
|
||||
|
||||
if (code === 403 && errorMessageDescription in intlMessages) {
|
||||
if (errorMessageDescription in intlMessages) {
|
||||
errorMessageDescription = intl.formatMessage(intlMessages[errorMessageDescription]);
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,7 @@ const propTypes = {
|
||||
const defaultProps = {
|
||||
ejectedReason: null,
|
||||
endedReason: null,
|
||||
callback: async () => {},
|
||||
};
|
||||
|
||||
class MeetingEnded extends PureComponent {
|
||||
@ -159,7 +160,9 @@ class MeetingEnded extends PureComponent {
|
||||
AudioManager.exitAudio();
|
||||
Storage.removeItem('getEchoTest');
|
||||
Storage.removeItem('isFirstJoin');
|
||||
Meteor.disconnect();
|
||||
this.props.callback().finally(() => {
|
||||
Meteor.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
setSelectedStar(starNumber) {
|
||||
|
@ -223,10 +223,15 @@ class Auth {
|
||||
}
|
||||
|
||||
this.loggedIn = false;
|
||||
this.isAuthenticating = true;
|
||||
|
||||
return this.validateAuthToken()
|
||||
.then(() => {
|
||||
this.loggedIn = true;
|
||||
this.uniqueClientSession = `${this.sessionToken}-${Math.random().toString(36).substring(6)}`;
|
||||
})
|
||||
.finally(() => {
|
||||
this.isAuthenticating = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -598,8 +598,11 @@
|
||||
"app.error.403": "You have been removed from the meeting",
|
||||
"app.error.404": "Not found",
|
||||
"app.error.408": "Authentication failed",
|
||||
"app.error.409": "Conflict",
|
||||
"app.error.410": "Meeting has ended",
|
||||
"app.error.500": "Ops, something went wrong",
|
||||
"app.error.503": "You have been disconnected",
|
||||
"app.error.disconnected.rejoin": "You are able to refresh the page to rejoin.",
|
||||
"app.error.userLoggedOut": "User has an invalid sessionToken due to log out",
|
||||
"app.error.ejectedUser": "User has an invalid sessionToken due to ejection",
|
||||
"app.error.joinedAnotherWindow": "This session seems to be opened in another browser window.",
|
||||
|
Loading…
Reference in New Issue
Block a user