Skip to content

Commit 03d535b

Browse files
committed
Fix #430: Handle event errors.
All event callback functions in xmpp now use a try-catch, and send any errors to Cadence.handleError to be displayed on the screen. The eventPresenceError and eventMessageError callback exploit this behavior and throw their errors rather than printing them directly.
1 parent b7e836c commit 03d535b

File tree

1 file changed

+65
-63
lines changed

1 file changed

+65
-63
lines changed

src/xmpp.js

+65-63
Original file line numberDiff line numberDiff line change
@@ -809,73 +809,72 @@ const xmpp = {
809809
* Any other presence that alters the user roster or client state.
810810
*/
811811
eventPresenceCallback(stanza) {
812-
if (!stanza) return true;
813-
const from = this.JID.parse(stanza.getAttribute('from'));
814-
// Discard any <presence/> that is not from the MUC domain.
815-
// (This client does not support direct non-MUC communication.)
816-
if (from.domain != config.xmpp.mucService) return true;
817-
818-
// Find the room and nickname that the presence came from, and the type.
819-
const room = from.node;
820-
const nick = from.resource;
821-
const type = stanza.getAttribute('type');
812+
try {
813+
const from = this.JID.parse(stanza.getAttribute('from'));
814+
// Discard any <presence/> that is not from the MUC domain.
815+
// (This client does not support direct non-MUC communication.)
816+
if (from.domain != config.xmpp.mucService) return true;
822817

823-
// Initialize the room roster if it doesn't exist yet.
824-
if (!this.roster[room]) this.roster[room] = {};
818+
// Find the room and nickname that the presence came from, and the type.
819+
const room = from.node;
820+
const nick = from.resource;
821+
const type = stanza.getAttribute('type');
825822

823+
// Initialize the room roster if it doesn't exist yet.
824+
if (!this.roster[room]) this.roster[room] = {};
826825

827-
if (type == 'error') {
828-
// We're not throwing this one, the error handling happens in here.
829-
const error = new this.StanzaError(stanza);
830-
switch (error.condition) {
831-
case 'conflict':
832-
if (room == this.room.current) {
833-
ui.messageError(strings.error.nickConflict, {nick});
834-
this.nick.target = this.nick.current;
835-
}
836-
else {
837-
ui.messageError(strings.error.joinConflict, {nick});
838-
if (this.nickConflictResolve()) {
839-
ui.messageInfo(strings.info.rejoinNick, {nick: this.nick.target});
840-
this.joinRoom(this.room.target, this.nick.target);
841-
}
842-
}
843-
break;
844-
case 'not-authorized':
845-
const password = prompt(strings.info.promptRoomPassword);
846-
if (password) {
847-
this.joinExistingRoom(room, password);
848-
}
849-
else {
850-
ui.messageError(strings.error.joinPassword, {room: this.room.available[room]});
851-
}
852-
break;
853-
case 'forbidden':
854-
ui.messageError(strings.error.joinBanned, {room: this.room.available[room]});
855-
break;
856-
case 'not-allowed':
857-
ui.messageError(strings.error.noCreate);
858-
break;
859-
case 'jid-malformed':
860-
this.nick.target = this.nick.current;
861-
ui.messageError(strings.error.badNick, {nick});
826+
if (type == 'error') {
827+
this.eventPresenceError(room, nick, stanza);
828+
return true;
862829
}
863-
return true;
864-
}
865830

866-
// Find the status codes.
867-
const item = stanza.querySelector('item');
868-
const codes = Array.from(stanza.querySelectorAll('status')).map(
869-
e => parseInt(e.getAttribute('code'))
870-
);
831+
// Find the status codes.
832+
const item = stanza.querySelector('item');
833+
const codes = Array.from(stanza.querySelectorAll('status')).map(
834+
e => parseInt(e.getAttribute('code'))
835+
);
871836

872-
if (type == 'unavailable')
873-
this.eventPresenceUnavailable(room, nick, codes, item, stanza);
874-
else
875-
this.eventPresenceDefault(room, nick, codes, item, stanza);
837+
if (type == 'unavailable')
838+
this.eventPresenceUnavailable(room, nick, codes, item, stanza);
839+
else
840+
this.eventPresenceDefault(room, nick, codes, item, stanza);
841+
}
842+
catch (e) {
843+
Cadence.handleError(e);
844+
}
876845
return true;
877846
},
878847

848+
eventPresenceError(room, nick, stanza) {
849+
// We're not throwing this one, the error handling happens in here.
850+
const error = new this.StanzaError(stanza);
851+
switch (error.condition) {
852+
case 'conflict':
853+
if (room == this.room.current) {
854+
this.nick.target = this.nick.current;
855+
throw new Cadence.Error(strings.error.nickConflict, {nick});
856+
}
857+
if (this.nickConflictResolve()) {
858+
ui.messageInfo(strings.info.rejoinNick, {nick: this.nick.target});
859+
this.joinRoom(this.room.target, this.nick.target);
860+
}
861+
else throw new Cadence.Error(strings.error.joinConflict, {nick});
862+
break;
863+
case 'not-authorized':
864+
const password = prompt(strings.info.promptRoomPassword);
865+
if (password) this.joinExistingRoom(room, password);
866+
else throw new Cadence.Error(strings.error.joinPassword, {room: this.room.available[room]});
867+
break;
868+
case 'forbidden':
869+
throw new Cadence.Error(strings.error.joinBanned, {room: this.room.available[room]});
870+
case 'not-allowed':
871+
throw new Cadence.Error(strings.error.noCreate);
872+
case 'jid-malformed':
873+
this.nick.target = this.nick.current;
874+
throw new Cadence.Error(strings.error.badNick, {nick});
875+
}
876+
},
877+
879878
/**
880879
* Handle presence stanzas of type `unavailable`.
881880
*/
@@ -1021,7 +1020,7 @@ const xmpp = {
10211020
* This function handles any <message> stanzas received.
10221021
*/
10231022
eventMessageCallback(stanza) {
1024-
if (stanza) {
1023+
try {
10251024
const from = this.JID.parse(stanza.getAttribute('from'));
10261025
const {domain, node, resource} = from;
10271026

@@ -1127,6 +1126,9 @@ const xmpp = {
11271126
if (resource != this.nick.current) ui.notify(message);
11281127
}
11291128
}
1129+
catch (e) {
1130+
Cadence.handleError(e);
1131+
}
11301132
return true;
11311133
},
11321134

@@ -1140,13 +1142,13 @@ const xmpp = {
11401142
const error = new xmpp.StanzaError(stanza);
11411143
switch (error.condition) {
11421144
case 'remote-server-not-found':
1143-
return ui.messageError(strings.error.notFound.domain, from);
1145+
throw new Cadence.Error(strings.error.notFound.domain, from);
11441146
case 'service-unavailable':
1145-
return ui.messageError(strings.error.notFound.node, from);
1147+
throw new Cadence.Error(strings.error.notFound.node, from);
11461148
case 'item-not-found':
1147-
return ui.messageError(strings.error.notFound.nick, {nick: from.resource});
1149+
throw new Cadence.Error(strings.error.notFound.nick, {nick: from.resource});
11481150
case 'forbidden':
1149-
return ui.messageError(strings.error.messageDenied, error);
1151+
throw new Cadence.Error(strings.error.messageDenied, error);
11501152
}
11511153
},
11521154

0 commit comments

Comments
 (0)