Don't hang indefinitely + nicer error messages

when a connection can't be established.
This commit is contained in:
JC Brand 2017-09-08 14:24:38 +02:00
parent f120103c55
commit bd913734e4
10 changed files with 156 additions and 71 deletions

View File

@ -1,5 +1,10 @@
# Changelog
## 3.2.2 (Unreleased)
- Don't hang indefinitely and provide nicer error messages when a connection
can't be established.
## 3.2.1 (2017-08-29)
### Bugfixes

View File

@ -1990,6 +1990,13 @@
white-space: normal; }
#conversejs #controlbox #converse-register .save-submit, #conversejs #controlbox #converse-login .save-submit {
color: #3AA569; }
#conversejs #controlbox #converse-register .conn-feedback p, #conversejs #controlbox #converse-login .conn-feedback p {
color: #578EA9;
padding-bottom: 0.5em; }
#conversejs #controlbox #converse-register .conn-feedback p.feedback-subject.error, #conversejs #controlbox #converse-login .conn-feedback p.feedback-subject.error {
font-weight: bold; }
#conversejs #controlbox #converse-register .conn-feedback p.error, #conversejs #controlbox #converse-login .conn-feedback p.error {
color: #A53214; }
#conversejs #controlbox #converse-register input, #conversejs #controlbox #converse-login input {
width: 100%;
margin: 0.5em 0; }

View File

@ -2058,6 +2058,13 @@ body {
white-space: normal; }
#conversejs #controlbox #converse-register .save-submit, #conversejs #controlbox #converse-login .save-submit {
color: #3AA569; }
#conversejs #controlbox #converse-register .conn-feedback p, #conversejs #controlbox #converse-login .conn-feedback p {
color: #578EA9;
padding-bottom: 0.5em; }
#conversejs #controlbox #converse-register .conn-feedback p.feedback-subject.error, #conversejs #controlbox #converse-login .conn-feedback p.feedback-subject.error {
font-weight: bold; }
#conversejs #controlbox #converse-register .conn-feedback p.error, #conversejs #controlbox #converse-login .conn-feedback p.error {
color: #A53214; }
#conversejs #controlbox #converse-register input, #conversejs #controlbox #converse-login input {
width: 100%;
margin: 0.5em 0; }

78
package-lock.json generated
View File

@ -3296,14 +3296,6 @@
}
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"string-width": {
"version": "1.0.2",
"bundled": true,
@ -3314,6 +3306,14 @@
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"stringstream": {
"version": "0.0.5",
"bundled": true,
@ -5080,6 +5080,7 @@
"integrity": "sha1-+Osa0A3FilUUNjtBylNCgX8L1kY=",
"dev": true,
"requires": {
"JSONStream": "1.3.1",
"abbrev": "1.1.0",
"ansi-regex": "2.1.1",
"ansicolors": "0.3.2",
@ -5110,7 +5111,6 @@
"inherits": "2.0.3",
"ini": "1.3.4",
"init-package-json": "1.10.1",
"JSONStream": "1.3.1",
"lazy-property": "1.0.0",
"lockfile": "1.0.3",
"lodash._baseindexof": "3.1.0",
@ -5173,6 +5173,27 @@
"write-file-atomic": "1.3.3"
},
"dependencies": {
"JSONStream": {
"version": "1.3.1",
"bundled": true,
"dev": true,
"requires": {
"jsonparse": "1.3.0",
"through": "2.3.8"
},
"dependencies": {
"jsonparse": {
"version": "1.3.0",
"bundled": true,
"dev": true
},
"through": {
"version": "2.3.8",
"bundled": true,
"dev": true
}
}
},
"abbrev": {
"version": "1.1.0",
"bundled": true,
@ -5514,27 +5535,6 @@
}
}
},
"JSONStream": {
"version": "1.3.1",
"bundled": true,
"dev": true,
"requires": {
"jsonparse": "1.3.0",
"through": "2.3.8"
},
"dependencies": {
"jsonparse": {
"version": "1.3.0",
"bundled": true,
"dev": true
},
"through": {
"version": "2.3.8",
"bundled": true,
"dev": true
}
}
},
"lazy-property": {
"version": "1.0.0",
"bundled": true,
@ -9005,15 +9005,6 @@
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
"dev": true
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"string-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
@ -9034,6 +9025,15 @@
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",

View File

@ -113,6 +113,18 @@
.save-submit {
color: $save-button-color;
}
.conn-feedback {
p {
color: $controlbox-head-color;
padding-bottom: 0.5em;
&.feedback-subject.error {
font-weight: bold;
}
&.error {
color: $error-color;
}
}
}
input {
width: 100%;
margin: 0.5em 0;

View File

@ -43,7 +43,6 @@ require.config({
"strophe.vcard": "node_modules/strophejs-plugin-vcard/strophe.vcard",
"text": "node_modules/text/text",
"tpl": "node_modules/lodash-template-loader/loader",
"typeahead": "components/typeahead.js/index",
"underscore": "src/underscore-shim",
"utils": "src/utils",
"xss": "node_modules/xss/dist/xss",
@ -108,8 +107,6 @@ require.config({
packages: [{
'name': 'moment',
// This location is relative to baseUrl. Choose bower_components
// or node_modules, depending on how moment was installed.
'location': 'node_modules/moment',
'main': 'moment'
}],

View File

@ -269,6 +269,17 @@
return this;
},
showLoginPanel () {
if (!_.isUndefined(this.loginpanel)) {
this.renderLoginPanel();
} else {
this.loginpanel.$el.find('input#jid').focus();
if (!this.loginpanel.$el.is(':visible')) {
this.loginpanel.$el.show();
}
}
},
renderLoginPanel () {
this.loginpanel = new _converse.LoginPanel({
'$parent': this.$el.find('.controlbox-panes'),
@ -390,6 +401,9 @@
'PREBIND': _converse.PREBIND,
'auto_login': _converse.auto_login,
'authentication': _converse.authentication,
'conn_feedback_class': _converse.connfeedback.get('klass'),
'conn_feedback_subject': _converse.connfeedback.get('subject'),
'conn_feedback_message': _converse.connfeedback.get('message'),
'label_username': __('XMPP Username:'),
'label_password': __('Password:'),
'label_anon_login': __('Click here to log in anonymously'),
@ -399,6 +413,7 @@
})
));
this.$tabs = cfg.$parent.parent().find('#controlbox-tabs');
_converse.connfeedback.on('change', this.showConnectionFeedback, this);
},
render () {
@ -410,6 +425,25 @@
return this;
},
showConnectionFeedback () {
const klass = _converse.connfeedback.get('klass');
function insert (text, el) {
el.textContent = text;
el.classList.remove('error');
if (klass) {
el.classList.add(klass);
}
}
insert(
_converse.connfeedback.get('subject'),
this.el.querySelector('.conn-feedback .feedback-subject')
)
insert(
_converse.connfeedback.get('message'),
this.el.querySelector('.conn-feedback .feedback-message')
)
},
authenticate (ev) {
/* Authenticate the user based on a form submission event.
*/
@ -743,6 +777,7 @@
this.updateOnlineCount();
const that = this;
_converse.api.waitUntil('initialized').then(() => {
this.render();
_converse.roster.on("add", that.updateOnlineCount, that);
_converse.roster.on('change', that.updateOnlineCount, that);
_converse.roster.on("destroy", that.updateOnlineCount, that);
@ -756,7 +791,7 @@
// artifacts (i.e. on page load the toggle is shown only to then
// seconds later be hidden in favor of the control box).
this.el.innerHTML = tpl_controlbox_toggle({
'label_toggle': __('Toggle chat')
'label_toggle': _converse.connection.connected ? __('Contacts') : __('Toggle chat')
})
return this;
},
@ -823,7 +858,7 @@
const view = _converse.chatboxviews.get('controlbox');
view.model.set({connected:false});
view.$('#controlbox-tabs').empty();
view.renderLoginPanel();
view.showLoginPanel();
};
_converse.on('disconnected', disconnect);

View File

@ -407,19 +407,10 @@
};
this.giveFeedback = function (subject, klass, message) {
_.forEach(document.querySelectorAll('.conn-feedback'), (el) => {
el.classList.add('conn-feedback');
el.textContent = subject;
if (klass) {
el.classList.add(klass);
} else {
el.classList.remove('error');
}
});
_converse.emit('feedback', {
_converse.connfeedback.set({
'subject': subject,
'klass': klass,
'message': message,
'subject': subject
'message': message
});
};
@ -462,6 +453,8 @@
* Will either start a teardown process for converse.js or attempt
* to reconnect.
*/
const reason = _converse.disconnection_reason;
if (_converse.disconnection_cause === Strophe.Status.AUTHFAIL) {
if (_converse.credentials_url && _converse.auto_reconnect) {
/* In this case, we reconnect, because we might be receiving
@ -473,7 +466,9 @@
return _converse.disconnect();
}
} else if (_converse.disconnection_cause === _converse.LOGOUT ||
_converse.disconnection_reason === "host-unknown" ||
(!_.isUndefined(reason) && reason === _.get(Strophe, 'ErrorCondition.NO_AUTH_MECH')) ||
reason === "host-unknown" ||
reason === "remote-connection-failed" ||
!_converse.auto_reconnect) {
return _converse.disconnect();
}
@ -494,7 +489,7 @@
}
};
this.onConnectStatusChanged = function (status, condition) {
this.onConnectStatusChanged = function (status, message) {
/* Callback method called by Strophe as the Strophe.Connection goes
* through various states while establishing or tearing down a
* connection.
@ -517,29 +512,38 @@
_converse.onConnected();
}
} else if (status === Strophe.Status.DISCONNECTED) {
_converse.setDisconnectionCause(status, condition);
_converse.setDisconnectionCause(status, message);
_converse.onDisconnected();
} else if (status === Strophe.Status.ERROR) {
_converse.giveFeedback(
__('Connection error'), 'error',
__('Connection error'),
'error',
__('An error occurred while connecting to the chat server.')
);
} else if (status === Strophe.Status.CONNECTING) {
_converse.giveFeedback(__('Connecting'));
_converse.giveFeedback(__('Connecting'));
} else if (status === Strophe.Status.AUTHENTICATING) {
_converse.giveFeedback(__('Authenticating'));
_converse.giveFeedback(__('Authenticating'));
} else if (status === Strophe.Status.AUTHFAIL) {
_converse.giveFeedback(__('Authentication Failed'), 'error');
_converse.setDisconnectionCause(status, condition, true);
_converse.giveFeedback(__('Authentication failed: '+message), 'error');
_converse.setDisconnectionCause(status, message, true);
_converse.onDisconnected();
} else if (status === Strophe.Status.CONNFAIL) {
let feedback = message;
if (message === "host-unknown" || message == "remote-connection-failed") {
feedback = __("Sorry, we could not connect to the XMPP host with domain: ") +
`\"${Strophe.getDomainFromJid(_converse.connection.jid)}\"`;
} else if (!_.isUndefined(message) && message === _.get(Strophe, 'ErrorCondition.NO_AUTH_MECH')) {
feedback = __("The XMPP server did not offer a supported authentication mechanism");
}
_converse.giveFeedback(
__('Connection failed'), 'error',
__('An error occurred while connecting to the chat server: '+condition)
__('Connection failed'),
'error',
feedback
);
_converse.setDisconnectionCause(status, condition);
_converse.setDisconnectionCause(status, message);
} else if (status === Strophe.Status.DISCONNECTING) {
_converse.setDisconnectionCause(status, condition);
_converse.setDisconnectionCause(status, message);
}
};
@ -749,7 +753,6 @@
_converse.roster.onConnected();
_converse.populateRoster();
_converse.registerPresenceHandler();
_converse.giveFeedback(__('Contacts'));
if (reconnecting) {
_converse.xmppstatus.sendPresence();
} else {
@ -1511,6 +1514,22 @@
}
});
this.ConnectionFeedback = Backbone.Model.extend({
initialize () {
this.on('change', this.emitConnectionFeedbackChange);
},
emitConnectionFeedbackChange () {
_converse.emit('connfeedback', {
'klass': _converse.connfeedback.get('klass'),
'message': _converse.connfeedback.get('message'),
'subject': _converse.connfeedback.get('subject')
});
}
});
this.connfeedback = new this.ConnectionFeedback();
this.XMPPStatus = Backbone.Model.extend({
initialize () {
this.set({

View File

@ -1 +1 @@
<span class="conn-feedback">{{{label_toggle}}}</span>
<span class="toggle-feedback">{{{label_toggle}}}</span>

View File

@ -2,6 +2,10 @@
{[ if (auto_login) { ]}
<span class="spinner login-submit"/>
{[ } ]}
<div class="conn-feedback">
<p class="feedback-subject {{ conn_feedback_class }}">{{ conn_feedback_subject }}</p>
<p class="feedback-message {{ conn_feedback_class }}">{{ conn_feedback_message }} </p>
</div>
{[ if (!auto_login) { ]}
{[ if (authentication == LOGIN || authentication == EXTERNAL) { ]}
<label>{{{label_username}}}</label>
@ -11,7 +15,6 @@
<input type="password" name="password" placeholder="{{{placeholder_password}}}">
{[ } ]}
<input class="pure-button button-primary" type="submit" value="{{{label_login}}}">
<span class="conn-feedback"></span>
{[ } ]}
{[ if (authentication == ANONYMOUS) { ]}
<input class="pure-button button-primary login-anon" type="submit" value="{{{label_anon_login}}}"/>