Browse Source

CONNECTION_FAILED error as object

Gradually, we exploded the error of CONNECTION_FAILED in multiple
redux state properties. The explosion makes maintenance harder because
the properties have to be updated in sync. Collect them in an object
resembling an Error instance.
master
Lyubo Marinov 8 years ago
parent
commit
4e0761a46a

+ 3
- 2
connection.js View File

83
             ConnectionEvents.CONNECTION_FAILED,
83
             ConnectionEvents.CONNECTION_FAILED,
84
             connectionFailedHandler);
84
             connectionFailedHandler);
85
 
85
 
86
-        function connectionFailedHandler(error, errMsg) {
87
-            APP.store.dispatch(connectionFailed(connection, error, errMsg));
86
+        function connectionFailedHandler(error, message, credentials) {
87
+            APP.store.dispatch(
88
+                connectionFailed(connection, error, message, credentials));
88
 
89
 
89
             if (isFatalJitsiConnectionError(error)) {
90
             if (isFatalJitsiConnectionError(error)) {
90
                 connection.removeEventListener(
91
                 connection.removeEventListener(

+ 17
- 2
react/features/authentication/actions.js View File

127
  * @private
127
  * @private
128
  * @returns {{
128
  * @returns {{
129
  *     type: UPGRADE_ROLE_FINISHED,
129
  *     type: UPGRADE_ROLE_FINISHED,
130
- *     error: Object
130
+ *     error: ?Object
131
  * }}
131
  * }}
132
  */
132
  */
133
-function _upgradeRoleFinished(error) {
133
+function _upgradeRoleFinished(error: ?Object) {
134
+    if (error) {
135
+        // Make the specified error object resemble an Error instance (to the
136
+        // extent that jitsi-meet needs it).
137
+        const {
138
+            authenticationError,
139
+            connectionError,
140
+            ...other
141
+        } = error;
142
+
143
+        error = { // eslint-disable-line no-param-reassign
144
+            name: authenticationError || connectionError,
145
+            ...other
146
+        };
147
+    }
148
+
134
     return {
149
     return {
135
         type: UPGRADE_ROLE_FINISHED,
150
         type: UPGRADE_ROLE_FINISHED,
136
         error
151
         error

+ 31
- 51
react/features/authentication/components/LoginDialog.native.js View File

64
         /**
64
         /**
65
          * The error which occurred during login/authentication.
65
          * The error which occurred during login/authentication.
66
          */
66
          */
67
-        _error: PropTypes.string,
68
-
69
-        /**
70
-         * The credential that the user has failed to authenticate with.
71
-         */
72
-        _errorCredentials: PropTypes.object,
73
-
74
-        /**
75
-         * Any extra details about the error provided by lib-jitsi-meet.
76
-         */
77
-        _errorDetails: PropTypes.string,
67
+        _error: PropTypes.object,
78
 
68
 
79
         /**
69
         /**
80
          * Redux store dispatch method.
70
          * Redux store dispatch method.
118
         const {
108
         const {
119
             _connecting: connecting,
109
             _connecting: connecting,
120
             _error: error,
110
             _error: error,
121
-            _errorCredentials: errorCredentials,
122
-            _errorDetails: errorDetails,
123
             t
111
             t
124
         } = this.props;
112
         } = this.props;
125
 
113
 
126
-        let messageKey = '';
127
-        const messageOptions = {};
114
+        let messageKey;
115
+        let messageOptions;
128
 
116
 
129
-        if (error === JitsiConnectionErrors.PASSWORD_REQUIRED) {
130
-            // Show the message if there's been a user ID or password provided.
131
-            messageKey
132
-                = errorCredentials
133
-                        && (errorCredentials.jid || errorCredentials.password)
134
-                    ? 'dialog.incorrectPassword'
135
-                    : null;
136
-        } else if (error) {
137
-            messageKey = 'dialog.connectErrorWithMsg';
138
-            messageOptions.msg = `${error} ${errorDetails}`;
117
+        if (error) {
118
+            const { name } = error;
119
+
120
+            if (name === JitsiConnectionErrors.PASSWORD_REQUIRED) {
121
+                // Show a message that the credentials are incorrect only if the
122
+                // credentials which have caused the connection to fail are the
123
+                // ones which the user sees.
124
+                const { credentials } = error;
125
+
126
+                if (credentials
127
+                        && credentials.jid
128
+                            === toJid(
129
+                                this.state.username,
130
+                                this.props._configHosts)
131
+                        && credentials.password === this.state.password) {
132
+                    messageKey = 'dialog.incorrectPassword';
133
+                }
134
+            } else if (name) {
135
+                messageKey = 'dialog.connectErrorWithMsg';
136
+                messageOptions || (messageOptions = {});
137
+                messageOptions.msg = `${name} ${error.message}`;
138
+            }
139
         }
139
         }
140
 
140
 
141
         return (
141
         return (
146
                 titleKey = 'dialog.passwordRequired'>
146
                 titleKey = 'dialog.passwordRequired'>
147
                 <View style = { styles.loginDialog }>
147
                 <View style = { styles.loginDialog }>
148
                     <TextInput
148
                     <TextInput
149
+                        autoCapitalize = { 'none' }
150
+                        autoCorrect = { false }
149
                         onChangeText = { this._onUsernameChange }
151
                         onChangeText = { this._onUsernameChange }
150
                         placeholder = { 'user@domain.com' }
152
                         placeholder = { 'user@domain.com' }
151
                         style = { styles.loginDialogTextInput }
153
                         style = { styles.loginDialogTextInput }
159
                     <Text style = { styles.loginDialogText }>
161
                     <Text style = { styles.loginDialogText }>
160
                         {
162
                         {
161
                             messageKey
163
                             messageKey
162
-                                ? t(messageKey, messageOptions)
164
+                                ? t(messageKey, messageOptions || {})
163
                                 : connecting
165
                                 : connecting
164
                                     ? t('connection.CONNECTING')
166
                                     ? t('connection.CONNECTING')
165
                                     : ''
167
                                     : ''
239
  *     _conference: JitsiConference,
241
  *     _conference: JitsiConference,
240
  *     _configHosts: Object,
242
  *     _configHosts: Object,
241
  *     _connecting: boolean,
243
  *     _connecting: boolean,
242
- *     _error: string,
243
- *     _errorCredentials: Object,
244
- *     _errorDetails: string
244
+ *     _error: Object
245
  * }}
245
  * }}
246
  */
246
  */
247
 function _mapStateToProps(state) {
247
 function _mapStateToProps(state) {
253
     const { hosts: configHosts } = state['features/base/config'];
253
     const { hosts: configHosts } = state['features/base/config'];
254
     const {
254
     const {
255
         connecting,
255
         connecting,
256
-        credentials,
257
-        error: connectionError,
258
-        errorMessage: connectionErrorMessage
256
+        error: connectionError
259
     } = state['features/base/connection'];
257
     } = state['features/base/connection'];
260
 
258
 
261
-    let error;
262
-    let errorCredentials;
263
-    let errorDetails;
264
-
265
-    if (connectionError) {
266
-        error = connectionError;
267
-        errorCredentials = credentials;
268
-        errorDetails = connectionErrorMessage;
269
-    } else if (upgradeRoleError) {
270
-        error
271
-            = upgradeRoleError.connectionError
272
-                || upgradeRoleError.authenticationError;
273
-        errorCredentials = upgradeRoleError.credentials;
274
-        errorDetails = upgradeRoleError.message;
275
-    }
276
-
277
     return {
259
     return {
278
         _conference: authRequired,
260
         _conference: authRequired,
279
         _configHosts: configHosts,
261
         _configHosts: configHosts,
280
         _connecting: Boolean(connecting) || Boolean(upgradeRoleInProgress),
262
         _connecting: Boolean(connecting) || Boolean(upgradeRoleInProgress),
281
-        _error: error,
282
-        _errorCredentials: errorCredentials,
283
-        _errorDetails: errorDetails
263
+        _error: connectionError || upgradeRoleError
284
     };
264
     };
285
 }
265
 }
286
 
266
 

+ 6
- 2
react/features/authentication/middleware.js View File

95
         _hideLoginDialog(store);
95
         _hideLoginDialog(store);
96
         break;
96
         break;
97
 
97
 
98
-    case CONNECTION_FAILED:
99
-        action.error === JitsiConnectionErrors.PASSWORD_REQUIRED
98
+    case CONNECTION_FAILED: {
99
+        const { error } = action;
100
+
101
+        error
102
+            && error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
100
             && store.dispatch(_openLoginDialog());
103
             && store.dispatch(_openLoginDialog());
101
         break;
104
         break;
105
+    }
102
 
106
 
103
     case STOP_WAIT_FOR_OWNER:
107
     case STOP_WAIT_FOR_OWNER:
104
         _clearExistingWaitForOwnerTimeout(store);
108
         _clearExistingWaitForOwnerTimeout(store);

+ 1
- 2
react/features/base/connection/actionTypes.js View File

26
  * {
26
  * {
27
  *     type: CONNECTION_FAILED,
27
  *     type: CONNECTION_FAILED,
28
  *     connection: JitsiConnection,
28
  *     connection: JitsiConnection,
29
- *     error: string,
30
- *     message: string
29
+ *     error: Object | string
31
  * }
30
  * }
32
  */
31
  */
33
 export const CONNECTION_FAILED = Symbol('CONNECTION_FAILED');
32
 export const CONNECTION_FAILED = Symbol('CONNECTION_FAILED');

+ 15
- 9
react/features/base/connection/actions.native.js View File

55
          * disconnected.
55
          * disconnected.
56
          *
56
          *
57
          * @param {string} message - Disconnect reason.
57
          * @param {string} message - Disconnect reason.
58
-         * @returns {void}
59
          * @private
58
          * @private
59
+         * @returns {void}
60
          */
60
          */
61
         function _onConnectionDisconnected(message: string) {
61
         function _onConnectionDisconnected(message: string) {
62
             connection.removeEventListener(
62
             connection.removeEventListener(
69
         /**
69
         /**
70
          * Resolves external promise when connection is established.
70
          * Resolves external promise when connection is established.
71
          *
71
          *
72
-         * @returns {void}
73
          * @private
72
          * @private
73
+         * @returns {void}
74
          */
74
          */
75
         function _onConnectionEstablished() {
75
         function _onConnectionEstablished() {
76
             unsubscribe();
76
             unsubscribe();
86
          * used to authenticate and the authentication failed.
86
          * used to authenticate and the authentication failed.
87
          * @param {string} [credentials.jid] - The XMPP user's ID.
87
          * @param {string} [credentials.jid] - The XMPP user's ID.
88
          * @param {string} [credentials.password] - The XMPP user's password.
88
          * @param {string} [credentials.password] - The XMPP user's password.
89
-         * @returns {void}
90
          * @private
89
          * @private
90
+         * @returns {void}
91
          */
91
          */
92
         function _onConnectionFailed(err, msg, credentials) {
92
         function _onConnectionFailed(err, msg, credentials) {
93
             unsubscribe();
93
             unsubscribe();
181
  * @returns {{
181
  * @returns {{
182
  *     type: CONNECTION_FAILED,
182
  *     type: CONNECTION_FAILED,
183
  *     connection: JitsiConnection,
183
  *     connection: JitsiConnection,
184
- *     credentials: Object,
185
- *     error: string,
186
- *     message: string
184
+ *     error: Object
187
  * }}
185
  * }}
188
  */
186
  */
189
 export function connectionFailed(
187
 export function connectionFailed(
194
     return {
192
     return {
195
         type: CONNECTION_FAILED,
193
         type: CONNECTION_FAILED,
196
         connection,
194
         connection,
197
-        credentials,
198
-        error,
199
-        message
195
+
196
+        // Make the error resemble an Error instance (to the extent that
197
+        // jitsi-meet needs it).
198
+        error: {
199
+            credentials:
200
+                credentials && Object.keys(credentials).length
201
+                    ? credentials
202
+                    : undefined,
203
+            message,
204
+            name: error
205
+        }
200
     };
206
     };
201
 }
207
 }
202
 
208
 

+ 5
- 12
react/features/base/connection/reducer.js View File

76
     return assign(state, {
76
     return assign(state, {
77
         connecting: undefined,
77
         connecting: undefined,
78
         connection,
78
         connection,
79
-        error: undefined,
80
-        errorMessage: undefined
79
+        error: undefined
81
     });
80
     });
82
 }
81
 }
83
 
82
 
93
  */
92
  */
94
 function _connectionFailed(
93
 function _connectionFailed(
95
         state: Object,
94
         state: Object,
96
-        { connection, credentials, error, message }: {
95
+        { connection, error }: {
97
             connection: Object,
96
             connection: Object,
98
-            credentials: ?Object,
99
-            error: string,
100
-            message: ?string
97
+            error: Object | string
101
         }) {
98
         }) {
102
     if (state.connection && state.connection !== connection) {
99
     if (state.connection && state.connection !== connection) {
103
         return state;
100
         return state;
106
     return assign(state, {
103
     return assign(state, {
107
         connecting: undefined,
104
         connecting: undefined,
108
         connection: undefined,
105
         connection: undefined,
109
-        credentials,
110
-        error,
111
-        errorMessage: message
106
+        error
112
     });
107
     });
113
 }
108
 }
114
 
109
 
127
         { connection }: { connection: Object }) {
122
         { connection }: { connection: Object }) {
128
     return assign(state, {
123
     return assign(state, {
129
         connecting: connection,
124
         connecting: connection,
130
-        credentials: undefined,
131
-        error: undefined,
132
-        errorMessage: undefined
125
+        error: undefined
133
     });
126
     });
134
 }
127
 }
135
 
128
 

+ 7
- 3
react/features/base/lib-jitsi-meet/functions.js View File

39
  * that category. I've currently named the category fatal because it appears to
39
  * that category. I've currently named the category fatal because it appears to
40
  * be used in the cases of unrecoverable errors that necessitate a reload.
40
  * be used in the cases of unrecoverable errors that necessitate a reload.
41
  *
41
  *
42
- * @param {string} error - The JitsiConnectionErrors instance to
43
- * categorize/classify.
42
+ * @param {Object|string} error - The JitsiConnectionErrors instance to
43
+ * categorize/classify or an Error-like object.
44
  * @returns {boolean} True if the specified JitsiConnectionErrors instance
44
  * @returns {boolean} True if the specified JitsiConnectionErrors instance
45
  * indicates a fatal JitsiConnection error; otherwise, false.
45
  * indicates a fatal JitsiConnection error; otherwise, false.
46
  */
46
  */
47
-export function isFatalJitsiConnectionError(error: string) {
47
+export function isFatalJitsiConnectionError(error: Object | string) {
48
+    if (typeof error !== 'string') {
49
+        error = error.name; // eslint-disable-line no-param-reassign
50
+    }
51
+
48
     return (
52
     return (
49
         error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR
53
         error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR
50
             || error === JitsiConnectionErrors.OTHER_ERROR
54
             || error === JitsiConnectionErrors.OTHER_ERROR

+ 4
- 2
react/features/overlay/reducer.js View File

89
  * @returns {Object} The new state of the feature overlay after the reduction of
89
  * @returns {Object} The new state of the feature overlay after the reduction of
90
  * the specified action.
90
  * the specified action.
91
  */
91
  */
92
-function _connectionFailed(state, { error, message }) {
92
+function _connectionFailed(state, { error }) {
93
     if (isFatalJitsiConnectionError(error)) {
93
     if (isFatalJitsiConnectionError(error)) {
94
+        const { message } = error;
95
+
94
         logger.error(`FATAL XMPP connection error: ${message}`);
96
         logger.error(`FATAL XMPP connection error: ${message}`);
95
 
97
 
96
         return assign(state, {
98
         return assign(state, {
99
             // From all of the cases above only CONNECTION_DROPPED_ERROR is
101
             // From all of the cases above only CONNECTION_DROPPED_ERROR is
100
             // considered a network type of failure.
102
             // considered a network type of failure.
101
             isNetworkFailure:
103
             isNetworkFailure:
102
-                error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR,
104
+                error.name === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR,
103
             reason: `xmpp-conn-dropped: ${message}`
105
             reason: `xmpp-conn-dropped: ${message}`
104
         });
106
         });
105
     }
107
     }

Loading…
Cancel
Save