[RN] Handle config loading errors

They will be stored in redux and the PageReloadOverlay will be displayed.

Note that this commit also introduces a subtle (and yet important!) change:
the location URL is now always set, regardless of the configuration loading or
not. This is needed in order for the retry logic to pick it up.
This commit is contained in:
Saúl Ibarra Corretgé 2017-11-29 15:15:57 +01:00 committed by Lyubo Marinov
parent 87a87eebb9
commit c05c8e0f1e
5 changed files with 67 additions and 18 deletions

View File

@ -1,7 +1,7 @@
/* @flow */
import { setRoom } from '../base/conference';
import { loadConfigError, setConfig } from '../base/config';
import { configWillLoad, loadConfigError, setConfig } from '../base/config';
import { setLocationURL } from '../base/connection';
import { loadConfig } from '../base/lib-jitsi-meet';
import { parseURIString } from '../base/util';
@ -44,6 +44,8 @@ function _appNavigateToMandatoryLocation(
): Promise<void> {
const { room } = newLocation;
dispatch(configWillLoad(newLocation));
return (
_loadConfig(newLocation)
.then(
@ -67,23 +69,20 @@ function _appNavigateToMandatoryLocation(
// config may or may not be required by the time the notification
// arrives.
const promise
= dispatch(setLocationURL(new URL(newLocation.toString())));
if (error) {
// XXX The failure could be, for example, because of a
// certificate-related error. In which case the connection will
// fail later in Strophe anyway.
dispatch(loadConfigError(error, newLocation));
// Cannot go to a room if its configuration failed to load.
if (room) {
dispatch(appNavigate(undefined));
return promise.then(() => {
dispatch(loadConfigError(error, newLocation));
throw error;
}
});
}
return (
dispatch(setLocationURL(new URL(newLocation.toString())))
.then(() => dispatch(setConfig(config))));
return promise.then(() => dispatch(setConfig(config)));
}
}

View File

@ -1,3 +1,14 @@
/**
* The redux action which signals that a configuration will be loaded for a
* specific locationURL.
*
* {
* type: CONFIG_WILL_LOAD,
* locationURL: string | URL
* }
*/
export const CONFIG_WILL_LOAD = Symbol('CONFIG_WILL_LOAD');
/**
* The redux action which signals that a configuration could not be loaded due
* to a specific error.

View File

@ -1,6 +1,27 @@
/* @flow */
import { LOAD_CONFIG_ERROR, SET_CONFIG } from './actionTypes';
import {
CONFIG_WILL_LOAD,
LOAD_CONFIG_ERROR,
SET_CONFIG
} from './actionTypes';
/**
* Signals that the configuration for a specific locationURL will be loaded now.
*
* @param {string|URL} locationURL - The URL of the location which necessitated
* the loading of a configuration.
* @returns {{
* type: CONFIG_WILL_LOAD,
* locationURL
* }}
*/
export function configWillLoad(locationURL: string | URL) {
return {
type: CONFIG_WILL_LOAD,
locationURL
};
}
/**
* Signals that a configuration could not be loaded due to a specific error.

View File

@ -4,7 +4,11 @@ import _ from 'lodash';
import { equals, ReducerRegistry, set } from '../redux';
import { SET_CONFIG } from './actionTypes';
import {
CONFIG_WILL_LOAD,
LOAD_CONFIG_ERROR,
SET_CONFIG
} from './actionTypes';
/**
* The initial state of the feature base/config when executing in a
@ -47,6 +51,16 @@ ReducerRegistry.register(
'features/base/config',
(state = _getInitialState(), action) => {
switch (action.type) {
case CONFIG_WILL_LOAD:
return {
error: undefined
};
case LOAD_CONFIG_ERROR:
return {
error: action.error
};
case SET_CONFIG:
return _setConfig(state, action);
@ -81,20 +95,21 @@ function _getInitialState() {
* @returns {Object} The new state of the feature base/lib-jitsi-meet after the
* reduction of the specified action.
*/
function _setConfig(state, action) {
let { config } = action;
function _setConfig(state, { config }) {
// The mobile app bundles jitsi-meet and lib-jitsi-meet at build time and
// does not download them at runtime from the deployment on which it will
// join a conference. The downloading is planned for implementation in the
// future (later rather than sooner) but is not implemented yet at the time
// of this writing and, consequently, we must provide legacy support in the
// meantime.
// eslint-disable-next-line no-param-reassign
config = _translateLegacyConfig(config);
const newState = _.merge(
{},
config,
{ error: undefined },
// The config of _getInitialState() is meant to override the config
// downloaded from the Jitsi Meet deployment because the former contains

View File

@ -66,12 +66,14 @@ export default class AbstractPageReloadOverlay extends Component<*, *> {
*/
static needsRender(state) {
const conferenceError = state['features/base/conference'].error;
const configError = state['features/base/config'].error;
const connectionError = state['features/base/connection'].error;
return (
(connectionError && isFatalJitsiConnectionError(connectionError))
|| (conferenceError
&& isFatalJitsiConferenceError(conferenceError))
|| configError
);
}
@ -253,10 +255,11 @@ export default class AbstractPageReloadOverlay extends Component<*, *> {
*/
export function abstractMapStateToProps(state: Object) {
const conferenceError = state['features/base/conference'].error;
const configError = state['features/base/config'].error;
const connectionError = state['features/base/connection'].error;
return {
isNetworkFailure: Boolean(connectionError),
reason: (connectionError || conferenceError).message
isNetworkFailure: Boolean(configError || connectionError),
reason: (configError || connectionError || conferenceError).message
};
}