diff --git a/spec/mam.js b/spec/mam.js index 952b37410..d5c37607f 100644 --- a/spec/mam.js +++ b/spec/mam.js @@ -230,9 +230,9 @@ 'from': contact_jid, 'type':'chat' }).c('body').t("Meet me at the dance"); - spyOn(_converse, 'log'); + spyOn(converse.env.log, 'warn'); _converse.connection._dataRecv(test_utils.createRequest(msg)); - expect(_converse.log).toHaveBeenCalledWith(`Ignoring alleged MAM message from ${msg.nodeTree.getAttribute('from')}`, Strophe.LogLevel.WARN); + expect(converse.env.log.warn).toHaveBeenCalledWith(`Ignoring alleged MAM message from ${msg.nodeTree.getAttribute('from')}`); msg = $msg({'id': _converse.connection.getUniqueId(), 'to': _converse.bare_jid}) .c('result', {'xmlns': 'urn:xmpp:mam:2', 'queryid':queryid, 'id': _converse.connection.getUniqueId()}) diff --git a/spec/messages.js b/spec/messages.js index e2c9f7961..6763656c9 100644 --- a/spec/messages.js +++ b/spec/messages.js @@ -518,7 +518,7 @@ // Ideally we wouldn't have to filter out headline // messages, but Prosody gives them the wrong 'type' :( - sinon.spy(_converse, 'log'); + sinon.spy(converse.env.log, 'info'); sinon.spy(_converse.api.chatboxes, 'get'); sinon.spy(u, 'isHeadlineMessage'); const msg = $msg({ @@ -528,15 +528,14 @@ id: (new Date()).getTime() }).c('body').t("This headline message will not be shown").tree(); await _converse.handleMessageStanza(msg); - expect(_converse.log.calledWith( - "onMessage: Ignoring incoming headline message from JID: montague.lit", - Strophe.LogLevel.INFO + expect(converse.env.log.info.calledWith( + "onMessage: Ignoring incoming headline message from JID: montague.lit" )).toBeTruthy(); expect(u.isHeadlineMessage.called).toBeTruthy(); expect(u.isHeadlineMessage.returned(true)).toBeTruthy(); expect(_converse.api.chatboxes.get.called).toBeFalsy(); // Remove sinon spies - _converse.log.restore(); + converse.env.log.info.restore(); _converse.api.chatboxes.get.restore(); u.isHeadlineMessage.restore(); done(); @@ -1853,7 +1852,7 @@ await test_utils.waitForRoster(_converse, 'current'); await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length) // Send a message from a different resource - spyOn(_converse, 'log'); + spyOn(converse.env.log, 'info'); spyOn(_converse.api.chatboxes, 'create').and.callThrough(); _converse.filter_by_resource = true; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; @@ -1866,9 +1865,9 @@ .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree(); await _converse.handleMessageStanza(msg); - expect(_converse.log).toHaveBeenCalledWith( - "onMessage: Ignoring incoming message intended for a different resource: romeo@montague.lit/some-other-resource", - Strophe.LogLevel.INFO); + expect(converse.env.log.info).toHaveBeenCalledWith( + "onMessage: Ignoring incoming message intended for a different resource: romeo@montague.lit/some-other-resource", + ); expect(_converse.api.chatboxes.create).not.toHaveBeenCalled(); _converse.filter_by_resource = false; diff --git a/spec/muc_messages.js b/spec/muc_messages.js index cdd80ac74..4924349dd 100644 --- a/spec/muc_messages.js +++ b/spec/muc_messages.js @@ -35,11 +35,10 @@ `); const view = _converse.api.chatviews.get(muc_jid); await view.model.onMessage(received_stanza); - spyOn(_converse, 'log'); + spyOn(converse.env.log, 'warn'); _converse.connection._dataRecv(test_utils.createRequest(received_stanza)); - expect(_converse.log).toHaveBeenCalledWith( - 'onMessage: Ignoring unencapsulated forwarded groupchat message', - Strophe.LogLevel.WARN + expect(converse.env.log.warn).toHaveBeenCalledWith( + 'onMessage: Ignoring unencapsulated forwarded groupchat message' ); expect(view.el.querySelectorAll('.chat-msg').length).toBe(0); expect(view.model.messages.length).toBe(0); @@ -193,12 +192,11 @@ 'type': 'groupchat' }).c('body').t('I am groot').tree(); const view = _converse.api.chatviews.get(muc_jid); - spyOn(_converse, 'log'); + spyOn(converse.env.log, 'warn'); await view.model.onMessage(msg); - expect(_converse.log).toHaveBeenCalledWith( + expect(converse.env.log.warn).toHaveBeenCalledWith( 'onMessage: Ignoring XEP-0280 "groupchat" message carbon, '+ - 'according to the XEP groupchat messages SHOULD NOT be carbon copied', - Strophe.LogLevel.WARN + 'according to the XEP groupchat messages SHOULD NOT be carbon copied' ); expect(view.el.querySelectorAll('.chat-msg').length).toBe(0); expect(view.model.messages.length).toBe(0); diff --git a/spec/roster.js b/spec/roster.js index c6b9c7071..3aac02a5a 100644 --- a/spec/roster.js +++ b/spec/roster.js @@ -39,7 +39,7 @@ expect(_converse.roster.models.length).toBe(1); expect(_converse.roster.at(0).get('jid')).toBe(contact_jid); - spyOn(_converse, 'log'); + spyOn(converse.env.log, 'warn'); let roster_push = u.toStanza(` @@ -47,10 +47,9 @@ `); _converse.connection._dataRecv(test_utils.createRequest(roster_push)); - expect(_converse.log.calls.count()).toBe(2); - expect(_converse.log).toHaveBeenCalledWith( - `Ignoring roster illegitimate roster push message from ${roster_push.getAttribute('from')}`, - Strophe.LogLevel.WARN + expect(converse.env.log.warn.calls.count()).toBe(1); + expect(converse.env.log.warn).toHaveBeenCalledWith( + `Ignoring roster illegitimate roster push message from ${roster_push.getAttribute('from')}` ); roster_push = u.toStanza(` @@ -59,10 +58,9 @@ `); _converse.connection._dataRecv(test_utils.createRequest(roster_push)); - expect(_converse.log.calls.count()).toBe(4); - expect(_converse.log).toHaveBeenCalledWith( - `Ignoring roster illegitimate roster push message from ${roster_push.getAttribute('from')}`, - Strophe.LogLevel.WARN + expect(converse.env.log.warn.calls.count()).toBe(2); + expect(converse.env.log.warn).toHaveBeenCalledWith( + `Ignoring roster illegitimate roster push message from ${roster_push.getAttribute('from')}` ); expect(_converse.roster.models.length).toBe(1); expect(_converse.roster.at(0).get('jid')).toBe(contact_jid); diff --git a/src/converse-chatview.js b/src/converse-chatview.js index d4734b671..4dfd236f5 100644 --- a/src/converse-chatview.js +++ b/src/converse-chatview.js @@ -14,6 +14,7 @@ import "converse-modal"; import { debounce, get, isString } from "lodash"; import { Overview } from "backbone.overview"; import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; import tpl_chatbox from "templates/chatbox.html"; import tpl_chatbox_head from "templates/chatbox_head.html"; import tpl_chatbox_message_form from "templates/chatbox_message_form.html"; @@ -184,7 +185,7 @@ converse.plugins.add('converse-chatview', { try { await _converse.api.vcard.update(this.model.contact.vcard, true); } catch (e) { - _converse.log(e, Strophe.LogLevel.FATAL); + log.fatal(e); this.alert(__('Sorry, something went wrong while trying to refresh'), 'danger'); } u.removeClass('fa-spin', refresh_icon); @@ -199,7 +200,7 @@ converse.plugins.add('converse-chatview', { this.model.contact.removeFromRoster( () => this.model.contact.destroy(), (err) => { - _converse.log(err, Strophe.LogLevel.ERROR); + log.error(err); _converse.api.alert('error', __('Error'), [ __('Sorry, there was an error while trying to remove %1$s as a contact.', this.model.contact.getDisplayName()) diff --git a/src/converse-controlbox.js b/src/converse-controlbox.js index dd235d24a..7b8774810 100644 --- a/src/converse-controlbox.js +++ b/src/converse-controlbox.js @@ -12,6 +12,7 @@ import "formdata-polyfill"; import bootstrap from "bootstrap.native"; import converse from "@converse/headless/converse-core"; import { get } from "lodash"; +import log from "@converse/headless/log"; import tpl_brand_heading from "templates/converse_brand_heading.html"; import tpl_controlbox from "templates/controlbox.html"; import tpl_controlbox_toggle from "templates/controlbox_toggle.html"; @@ -514,7 +515,7 @@ converse.plugins.add('converse-controlbox', { _converse.chatboxviews.insertRowColumn(this.render().el); _converse.api.waitUntil('initialized') .then(this.render.bind(this)) - .catch(e => _converse.log(e, Strophe.LogLevel.FATAL)); + .catch(e => log.fatal(e)); }, render () { @@ -597,7 +598,7 @@ converse.plugins.add('converse-controlbox', { _converse.api.waitUntil('chatBoxViewsInitialized') .then(addControlBox) - .catch(e => _converse.log(e, Strophe.LogLevel.FATAL)); + .catch(e => log.fatal(e)); _converse.api.listen.on('chatBoxesFetched', () => { const controlbox = _converse.chatboxes.get('controlbox') || addControlBox(); diff --git a/src/converse-message-view.js b/src/converse-message-view.js index 40b5c1e31..b185870fd 100644 --- a/src/converse-message-view.js +++ b/src/converse-message-view.js @@ -12,6 +12,7 @@ import URI from "urijs"; import converse from "@converse/headless/converse-core"; import { debounce } from 'lodash' import filesize from "filesize"; +import log from "@converse/headless/log"; import tpl_csn from "templates/csn.html"; import tpl_file_progress from "templates/file_progress.html"; import tpl_info from "templates/info.html"; @@ -128,7 +129,7 @@ converse.plugins.add('converse-message-view', { this.renderChatStateNotification() } else if (this.model.get('file') && !this.model.get('oob_url')) { if (!this.model.file) { - _converse.log("Attempted to render a file upload message with no file data"); + log.error("Attempted to render a file upload message with no file data"); return this.el; } this.renderFileUploadProgresBar(); diff --git a/src/converse-minimize.js b/src/converse-minimize.js index 269cb0344..91e39cb9a 100644 --- a/src/converse-minimize.js +++ b/src/converse-minimize.js @@ -9,15 +9,16 @@ import "converse-chatview"; import { Overview } from "backbone.overview"; import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; import tpl_chatbox_minimize from "templates/chatbox_minimize.html"; import tpl_chats_panel from "templates/chats_panel.html"; import tpl_toggle_chats from "templates/toggle_chats.html"; import tpl_trimmed_chat from "templates/trimmed_chat.html"; - -const { _ , Backbone, Strophe, dayjs } = converse.env; +const { _ , Backbone, dayjs } = converse.env; const u = converse.env.utils; + converse.plugins.add('converse-minimize', { /* Optional dependencies are other plugins which might be * overridden or relied upon, and therefore need to be loaded before @@ -572,8 +573,7 @@ converse.plugins.add('converse-minimize', { * @example _converse.api.listen.on('minimizedChatsInitialized', () => { ... }); */ _converse.api.trigger('minimizedChatsInitialized'); - }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); - + }).catch(e => log.fatal(e)); const debouncedTrimChats = _.debounce(() => _converse.chatboxviews.trimChats(), 250); _converse.api.listen.on('chatBoxInsertedIntoDOM', view => _converse.chatboxviews.trimChats(view)); diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index 3e4efa634..d5cbd463a 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -15,6 +15,7 @@ import "formdata-polyfill"; import "@converse/headless/utils/muc"; import { OrderedListView } from "backbone.overview"; import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; import tpl_add_chatroom_modal from "templates/add_chatroom_modal.html"; import tpl_chatarea from "templates/chatarea.html"; import tpl_chatroom from "templates/chatroom.html"; @@ -219,7 +220,7 @@ converse.plugins.add('converse-muc-views', { parent_el.insertAdjacentHTML('beforeend', tpl_spinner()); _converse.api.disco.info(ev.target.getAttribute('data-room-jid'), null) .then(stanza => insertRoomInfo(parent_el, stanza)) - .catch(e => _converse.log(e, Strophe.LogLevel.ERROR)); + .catch(e => log.error(e)); } } @@ -353,7 +354,7 @@ converse.plugins.add('converse-muc-views', { }) .catch(err => { this.alert(__('Sorry, something went wrong while trying to set the affiliation'), 'danger'); - _converse.log(err, Strophe.LogLevel.ERROR); + log.error(err); }); }, @@ -377,7 +378,7 @@ converse.plugins.add('converse-muc-views', { } else { this.alert(__('Sorry, something went wrong while trying to set the role'), 'danger'); if (u.isErrorObject(e)) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } } } @@ -1149,7 +1150,7 @@ converse.plugins.add('converse-muc-views', { }, onCommandError (err) { - _converse.log(err, Strophe.LogLevel.FATAL); + log.fatal(err); this.showErrorMessage(__("Sorry, an error happened while running the command. Check your browser's developer console for details.")); }, @@ -1366,7 +1367,7 @@ converse.plugins.add('converse-muc-views', { this.showSpinner(); this.model.fetchRoomConfiguration() .then(iq => this.renderConfigurationForm(iq)) - .catch(e => _converse.log(e, Strophe.LogLevel.ERROR)); + .catch(e => log.error(e)); } else { this.closeForm(); } @@ -2125,7 +2126,7 @@ converse.plugins.add('converse-muc-views', { // Features could have been added before the controlbox was // initialized. We're only interested in MUC _converse.disco_entities.each(entity => featureAdded(entity.features.findWhere({'var': Strophe.NS.MUC }))); - }).catch(e => _converse.log(e, Strophe.LogLevel.ERROR)); + }).catch(e => log.error(e)); } function fetchAndSetMUCDomain (controlboxview) { diff --git a/src/converse-notification.js b/src/converse-notification.js index 03033614a..0d0d41926 100644 --- a/src/converse-notification.js +++ b/src/converse-notification.js @@ -9,6 +9,7 @@ */ import converse from "@converse/headless/converse-core"; import { get } from "lodash"; +import log from "@converse/headless/log"; const { Strophe, sizzle } = converse.env; const u = converse.env.utils; @@ -150,9 +151,7 @@ converse.plugins.add('converse-notification', { title = __("%1$s says", Strophe.getResourceFromJid(full_from_jid)); } else { if (_converse.roster === undefined) { - _converse.log( - "Could not send notification, because roster is undefined", - Strophe.LogLevel.ERROR); + log.error("Could not send notification, because roster is undefined"); return; } roster_item = _converse.roster.get(from_jid); diff --git a/src/converse-omemo.js b/src/converse-omemo.js index 70488ff77..7e70b6e7a 100644 --- a/src/converse-omemo.js +++ b/src/converse-omemo.js @@ -10,6 +10,7 @@ */ import "converse-profile"; import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; import tpl_toolbar_omemo from "templates/toolbar_omemo.html"; const { Backbone, Strophe, sizzle, $build, $iq, $msg, _ } = converse.env; @@ -122,7 +123,7 @@ converse.plugins.add('converse-omemo', { .catch(err => { const { _converse } = this.__super__, { __ } = _converse; - _converse.log(err, Strophe.LogLevel.ERROR); + log.error(err); _converse.api.alert( Strophe.LogLevel.ERROR, __('Error'), [__('Sorry, an error occurred while trying to remove the devices.')] @@ -312,7 +313,7 @@ converse.plugins.add('converse-omemo', { 'type': 'error', }); } - _converse.log(`${e.name} ${e.message}`, Strophe.LogLevel.ERROR); + log.error(`${e.name} ${e.message}`); }, async handleDecryptedWhisperMessage (attrs, key_and_tag) { @@ -414,10 +415,10 @@ converse.plugins.add('converse-omemo', { err_msgs.push(e.iq.outerHTML); } _converse.api.alert('error', __('Error'), err_msgs); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } else if (e.user_facing) { _converse.api.alert('error', __('Error'), [e.message]); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } else { throw e; } @@ -557,11 +558,8 @@ converse.plugins.add('converse-omemo', { const session = await buildSession(device); return session; } catch (e) { - _converse.log( - `Could not build an OMEMO session for device ${device.get('id')}`, - Strophe.LogLevel.ERROR - ); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(`Could not build an OMEMO session for device ${device.get('id')}`); + log.error(e); return null; } } @@ -845,7 +843,7 @@ converse.plugins.add('converse-omemo', { Object.keys(this.getPreKeys()) ); if (missing_keys.length < 1) { - _converse.log("No missing prekeys to generate for our own device", Strophe.LogLevel.WARN); + log.warn("No missing prekeys to generate for our own device"); return Promise.resolve(); } const keys = await Promise.all(missing_keys.map(id => libsignal.KeyHelper.generatePreKey(parseInt(id, 10)))); @@ -908,11 +906,8 @@ converse.plugins.add('converse-omemo', { } }, 'error': (model, resp) => { - _converse.log( - "Could not fetch OMEMO session from cache, we'll generate a new one.", - Strophe.LogLevel.WARN - ); - _converse.log(resp, Strophe.LogLevel.WARN); + log.warn("Could not fetch OMEMO session from cache, we'll generate a new one."); + log.warn(resp); this.generateBundle().then(resolve).catch(reject); } }); @@ -996,10 +991,10 @@ converse.plugins.add('converse-omemo', { ids = await this.fetchDevicesFromServer() } catch (e) { if (e === null) { - _converse.log(`Timeout error while fetching devices for ${this.get('jid')}`, Strophe.LogLevel.ERROR); + log.error(`Timeout error while fetching devices for ${this.get('jid')}`); } else { - _converse.log(`Could not fetch devices for ${this.get('jid')}`, Strophe.LogLevel.ERROR); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(`Could not fetch devices for ${this.get('jid')}`); + log.error(e); } this.destroy(); } @@ -1014,7 +1009,7 @@ converse.plugins.add('converse-omemo', { this._devices_promise = new Promise(resolve => { this.devices.fetch({ 'success': c => resolve(this.onDevicesFound(c)), - 'error': (m, e) => { _converse.log(e, Strophe.LogLevel.ERROR); resolve(); } + 'error': (m, e) => { log.error(e); resolve(); } }); }); } @@ -1049,7 +1044,7 @@ converse.plugins.add('converse-omemo', { try { iq = await _converse.api.sendIQ(stanza); } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); return []; } const device_ids = sizzle(`list[xmlns="${Strophe.NS.OMEMO}"] device`, iq).map(dev => dev.getAttribute('id')); @@ -1161,7 +1156,7 @@ converse.plugins.add('converse-omemo', { updateBundleFromStanza(message); } } catch (e) { - _converse.log(e.message, Strophe.LogLevel.ERROR); + log.error(e.message); } return true; }, null, 'message', 'headline'); @@ -1189,8 +1184,8 @@ converse.plugins.add('converse-omemo', { await restoreOMEMOSession(); await _converse.omemo_store.publishBundle(); } catch (e) { - _converse.log("Could not initialize OMEMO support", Strophe.LogLevel.ERROR); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error("Could not initialize OMEMO support"); + log.error(e); return; } /** @@ -1252,11 +1247,11 @@ converse.plugins.add('converse-omemo', { _converse.api.listen.on('userDetailsModalInitialized', (contact) => { const jid = contact.get('jid'); - _converse.generateFingerprints(jid).catch(e => _converse.log(e, Strophe.LogLevel.ERROR)); + _converse.generateFingerprints(jid).catch(e => log.error(e)); }); _converse.api.listen.on('profileModalInitialized', () => { - _converse.generateFingerprints(_converse.bare_jid).catch(e => _converse.log(e, Strophe.LogLevel.ERROR)); + _converse.generateFingerprints(_converse.bare_jid).catch(e => log.error(e)); }); _converse.api.listen.on('afterTearDown', () => (delete _converse.omemo_store)); diff --git a/src/converse-profile.js b/src/converse-profile.js index d52c1ae28..c7e5811ab 100644 --- a/src/converse-profile.js +++ b/src/converse-profile.js @@ -13,12 +13,13 @@ import "converse-modal"; import "formdata-polyfill"; import bootstrap from "bootstrap.native"; import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; import tpl_chat_status_modal from "templates/chat_status_modal.html"; import tpl_client_info_modal from "templates/client_info_modal.html"; import tpl_profile_modal from "templates/profile_modal.html"; import tpl_profile_view from "templates/profile_view.html"; -const { Strophe, sizzle } = converse.env; +const { sizzle } = converse.env; const u = converse.env.utils; @@ -102,7 +103,7 @@ converse.plugins.add('converse-profile', { _converse.api.vcard.set(_converse.bare_jid, data) .then(() => _converse.api.vcard.update(this.model.vcard, true)) .catch((err) => { - _converse.log(err, Strophe.LogLevel.FATAL); + log.fatal(err); _converse.api.show('error', __('Error'), [ __("Sorry, an error happened while trying to save your profile data."), __("You can check your browser's developer console for any error output.") diff --git a/src/converse-push.js b/src/converse-push.js index e7669d7be..7c613d90c 100644 --- a/src/converse-push.js +++ b/src/converse-push.js @@ -10,6 +10,7 @@ * an "App Server" as defined in XEP-0357 */ import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; const { Strophe, $iq, _ } = converse.env; @@ -34,10 +35,8 @@ converse.plugins.add('converse-push', { return; } if (!(await _converse.api.disco.supports(Strophe.NS.PUSH, domain || _converse.bare_jid))) { - return _converse.log( - `Not disabling push app server "${push_app_server.jid}", no disco support from your server.`, - Strophe.LogLevel.WARN - ); + log.warn(`Not disabling push app server "${push_app_server.jid}", no disco support from your server.`); + return; } const stanza = $iq({'type': 'set'}); if (domain !== _converse.bare_jid) { @@ -52,8 +51,8 @@ converse.plugins.add('converse-push', { } _converse.api.sendIQ(stanza) .catch(e => { - _converse.log(`Could not disable push app server for ${push_app_server.jid}`, Strophe.LogLevel.ERROR); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(`Could not disable push app server for ${push_app_server.jid}`); + log.error(e); }); } @@ -63,9 +62,8 @@ converse.plugins.add('converse-push', { } const identity = await _converse.api.disco.getIdentity('pubsub', 'push', push_app_server.jid); if (!identity) { - return _converse.log( - `Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.`, - Strophe.LogLevel.WARN + return log.warn( + `Not enabling push the service "${push_app_server.jid}", it doesn't have the right disco identtiy.` ); } const result = await Promise.all([ @@ -73,10 +71,8 @@ converse.plugins.add('converse-push', { _converse.api.disco.supports(Strophe.NS.PUSH, domain) ]); if (!result[0] && !result[1]) { - return _converse.log( - `Not enabling push app server "${push_app_server.jid}", no disco support from your server.`, - Strophe.LogLevel.WARN - ); + log.warn(`Not enabling push app server "${push_app_server.jid}", no disco support from your server.`); + return; } const stanza = $iq({'type': 'set'}); if (domain !== _converse.bare_jid) { @@ -110,8 +106,8 @@ converse.plugins.add('converse-push', { try { await Promise.all(enabled.concat(disabled)); } catch (e) { - _converse.log('Could not enable or disable push App Server', Strophe.LogLevel.ERROR); - if (e) _converse.log(e, Strophe.LogLevel.ERROR); + log.error('Could not enable or disable push App Server'); + if (e) log.error(e); } finally { push_enabled.push(domain); } diff --git a/src/converse-register.js b/src/converse-register.js index 957cc8020..ea6a5dc5e 100644 --- a/src/converse-register.js +++ b/src/converse-register.js @@ -12,6 +12,7 @@ */ import "converse-controlbox"; import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; import tpl_form_input from "templates/form_input.html"; import tpl_form_username from "templates/form_username.html"; import tpl_register_link from "templates/register_link.html"; @@ -142,7 +143,7 @@ converse.plugins.add('converse-register', { _converse.api.waitUntil('controlBoxInitialized').then(() => { const controlbox = _converse.chatboxes.get('controlbox') controlbox.set({'active-form': value}); - }).catch(e => _converse.log(e, Strophe.LogLevel.FATAL)); + }).catch(e => log.fatal(e)); } _converse.router.route('converse/login', () => setActiveForm('login')); _converse.router.route('converse/register', () => setActiveForm('register')); @@ -402,7 +403,7 @@ converse.plugins.add('converse-register', { * @param { integer } status_code - The Strophe.Status status code */ onConnectStatusChanged(status_code) { - _converse.log('converse-register: onConnectStatusChanged'); + log.debug('converse-register: onConnectStatusChanged'); if (_.includes([ Strophe.Status.DISCONNECTED, Strophe.Status.CONNFAIL, @@ -411,13 +412,12 @@ converse.plugins.add('converse-register', { Strophe.Status.CONFLICT ], status_code)) { - _converse.log( - `Problem during registration: Strophe.Status is ${_converse.CONNECTION_STATUS[status_code]}`, - Strophe.LogLevel.ERROR + log.error( + `Problem during registration: Strophe.Status is ${_converse.CONNECTION_STATUS[status_code]}` ); this.abortRegistration(); } else if (status_code === Strophe.Status.REGISTERED) { - _converse.log("Registered successfully."); + log.debug("Registered successfully."); _converse.connection.reset(); this.showSpinner(); @@ -645,7 +645,7 @@ converse.plugins.add('converse-register', { this.fields[_var.toLowerCase()] = _.get(field.querySelector('value'), 'textContent', ''); } else { // TODO: other option seems to be type="fixed" - _converse.log("Found field we couldn't parse", Strophe.LogLevel.WARN); + log.warn("Found field we couldn't parse"); } }); this.form_type = 'xform'; @@ -661,7 +661,7 @@ converse.plugins.add('converse-register', { */ _onRegisterIQ (stanza) { if (stanza.getAttribute("type") === "error") { - _converse.log("Registration failed.", Strophe.LogLevel.ERROR); + log.error("Registration failed."); this.reportErrors(stanza); let error = stanza.getElementsByTagName("error"); diff --git a/src/converse-rosterview.js b/src/converse-rosterview.js index 46bf90ba9..c7dd67cae 100644 --- a/src/converse-rosterview.js +++ b/src/converse-rosterview.js @@ -13,6 +13,7 @@ import "formdata-polyfill"; import { OrderedListView } from "backbone.overview"; import SHA1 from 'strophe.js/src/sha1'; import converse from "@converse/headless/converse-core"; +import log from "@converse/headless/log"; import tpl_add_contact_modal from "templates/add_contact_modal.html"; import tpl_group_header from "templates/group_header.html"; import tpl_pending_contact from "templates/pending_contact.html"; @@ -504,7 +505,7 @@ converse.plugins.add('converse-rosterview', { this.model.destroy(); } } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); _converse.api.alert('error', __('Error'), [__('Sorry, there was an error while trying to remove %1$s as a contact.', this.model.getDisplayName())] ); @@ -933,10 +934,9 @@ converse.plugins.add('converse-rosterview', { this.addExistingContact(contact, options); } else { if (!_converse.allow_contact_requests) { - _converse.log( + log.debug( `Not adding requesting or pending contact ${contact.get('jid')} `+ - `because allow_contact_requests is false`, - Strophe.LogLevel.DEBUG + `because allow_contact_requests is false` ); return; } @@ -971,7 +971,7 @@ converse.plugins.add('converse-rosterview', { /* Place the rosterview inside the "Contacts" panel. */ _converse.api.waitUntil('rosterViewInitialized') .then(() => view.controlbox_pane.el.insertAdjacentElement('beforeEnd', _converse.rosterview.el)) - .catch(e => _converse.log(e, Strophe.LogLevel.FATAL)); + .catch(e => log.fatal(e)); } insertRoster(); view.model.on('change:connected', insertRoster); diff --git a/src/headless/converse-bookmarks.js b/src/headless/converse-bookmarks.js index 6e03ef85d..ba0677550 100644 --- a/src/headless/converse-bookmarks.js +++ b/src/headless/converse-bookmarks.js @@ -12,6 +12,7 @@ import "@converse/headless/converse-muc"; import converse from "@converse/headless/converse-core"; import { get } from "lodash"; +import log from "./log"; const { Backbone, Strophe, $iq, sizzle } = converse.env; const u = converse.env.utils; @@ -105,7 +106,7 @@ converse.plugins.add('converse-bookmarks', { initialize () { this.on('add', bm => this.openBookmarkedRoom(bm) .then(bm => this.markRoomAsBookmarked(bm)) - .catch(e => _converse.log(e, Strophe.LogLevel.FATAL)) + .catch(e => log.fatal(e)) ); this.on('remove', this.markRoomAsUnbookmarked, this); @@ -172,8 +173,8 @@ converse.plugins.add('converse-bookmarks', { }, onBookmarkError (iq, options) { - _converse.log("Error while trying to add bookmark", Strophe.LogLevel.ERROR); - _converse.log(iq); + log.error("Error while trying to add bookmark"); + log.error(iq); _converse.api.alert( 'error', __('Error'), [__("Sorry, something went wrong while trying to save your bookmark.")] ); @@ -232,14 +233,14 @@ converse.plugins.add('converse-bookmarks', { onBookmarksReceivedError (deferred, iq) { if (iq === null) { - _converse.log('Error: timeout while fetching bookmarks', Strophe.LogLevel.ERROR); + log.error('Error: timeout while fetching bookmarks'); _converse.api.alert('error', __('Timeout Error'), [__("The server did not return your bookmarks within the allowed time. "+ "You can reload the page to request them again.")] ); } else { - _converse.log('Error while fetching bookmarks', Strophe.LogLevel.ERROR); - _converse.log(iq, Strophe.LogLevel.DEBUG); + log.error('Error while fetching bookmarks'); + log.error(iq); } if (deferred) { if (iq.querySelector('error[type="cancel"] item-not-found')) { @@ -305,7 +306,7 @@ converse.plugins.add('converse-bookmarks', { if (sizzle('event[xmlns="'+Strophe.NS.PUBSUB+'#event"] items[node="storage:bookmarks"]', message).length) { _converse.api.waitUntil('bookmarksInitialized') .then(() => _converse.bookmarks.createBookmarksFromStanza(message)) - .catch(e => _converse.log(e, Strophe.LogLevel.FATAL)); + .catch(e => log.fatal(e)); } }, null, 'message', 'headline', null, _converse.bare_jid); diff --git a/src/headless/converse-bosh.js b/src/headless/converse-bosh.js index a95701a06..6419dc907 100644 --- a/src/headless/converse-bosh.js +++ b/src/headless/converse-bosh.js @@ -10,6 +10,7 @@ */ import 'strophe.js/src/bosh'; import converse from "./converse-core"; +import log from "./log"; const { Backbone, Strophe } = converse.env; @@ -94,9 +95,7 @@ converse.plugins.add('converse-bosh', { _converse.connection.restore(jid, _converse.onConnectStatusChanged); return true; } catch (e) { - _converse.log( - "Could not restore session for jid: "+ - jid+" Error message: "+e.message, Strophe.LogLevel.WARN); + log.warn("Could not restore session for jid: "+jid+" Error message: "+e.message); return false; } } diff --git a/src/headless/converse-chat.js b/src/headless/converse-chat.js index 51606393a..697da5df4 100644 --- a/src/headless/converse-chat.js +++ b/src/headless/converse-chat.js @@ -1,6 +1,7 @@ import { get, isObject, isString, propertyOf } from "lodash"; import converse from "./converse-core"; import filesize from "filesize"; +import log from "./log"; const { $msg, Backbone, Strophe, dayjs, sizzle, utils } = converse.env; const u = converse.env.utils; @@ -98,7 +99,7 @@ converse.plugins.add('converse-chat', { try { this.destroy() } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } }, @@ -164,7 +165,7 @@ converse.plugins.add('converse-chat', { try { stanza = await this.sendSlotRequestStanza(); } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); return this.save({ 'type': 'error', 'message': __("Sorry, could not determine upload URL."), @@ -190,7 +191,7 @@ converse.plugins.add('converse-chat', { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState === XMLHttpRequest.DONE) { - _converse.log("Status: " + xhr.status, Strophe.LogLevel.INFO); + log.info("Status: " + xhr.status); if (xhr.status === 200 || xhr.status === 201) { this.save({ 'upload': _converse.SUCCESS, @@ -318,7 +319,7 @@ converse.plugins.add('converse-chat', { fetchMessages () { if (this.messages.fetched) { - _converse.log(`Not re-fetching messages for ${this.get('jid')}`, Strophe.LogLevel.INFO); + log.info(`Not re-fetching messages for ${this.get('jid')}`); return; } this.messages.fetched = u.getResolveablePromise(); @@ -356,7 +357,7 @@ converse.plugins.add('converse-chat', { this.messages.reset(); } catch (e) { this.messages.trigger('reset'); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } finally { delete this.messages.fetched; } @@ -368,7 +369,7 @@ converse.plugins.add('converse-chat', { return this.destroy({success, 'error': (m, e) => reject(e)}) }); } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } finally { if (_converse.clear_messages_on_reconnection) { await this.clearMessages(); @@ -401,7 +402,7 @@ converse.plugins.add('converse-chat', { const auto_join = _converse.auto_join_private_chats.concat(room_jids); if (_converse.singleton && !auto_join.includes(attrs.jid) && !_converse.auto_join_on_invite) { const msg = `${attrs.jid} is not allowed because singleton is true and it's not being auto_joined`; - _converse.log(msg, Strophe.LogLevel.WARN); + log.warn(msg); return msg; } }, @@ -625,11 +626,8 @@ converse.plugins.add('converse-chat', { if (markers.length === 0) { return false; } else if (markers.length > 1) { - _converse.log( - 'handleChatMarker: Ignoring incoming stanza with multiple message markers', - Strophe.LogLevel.ERROR - ); - _converse.log(stanza, Strophe.LogLevel.ERROR); + log.error('handleChatMarker: Ignoring incoming stanza with multiple message markers'); + log.error(stanza); return false; } else { const marker = markers.pop(); @@ -1088,8 +1086,8 @@ converse.plugins.add('converse-chat', { .c('not-allowed', {xmlns:"urn:ietf:params:xml:ns:xmpp-stanzas"}).up() .c('text', {xmlns:"urn:ietf:params:xml:ns:xmpp-stanzas"}).t(text) ); - _converse.log(`Rejecting message stanza with the following reason: ${text}`, Strophe.LogLevel.WARN); - _converse.log(stanza, Strophe.LogLevel.WARN); + log.warn(`Rejecting message stanza with the following reason: ${text}`); + log.warn(stanza); } @@ -1123,17 +1121,11 @@ converse.plugins.add('converse-chat', { const to_resource = Strophe.getResourceFromJid(to_jid); if (_converse.filter_by_resource && (to_resource && to_resource !== _converse.resource)) { - return _converse.log( - `onMessage: Ignoring incoming message intended for a different resource: ${to_jid}`, - Strophe.LogLevel.INFO - ); + return log.info(`onMessage: Ignoring incoming message intended for a different resource: ${to_jid}`); } else if (utils.isHeadlineMessage(_converse, stanza)) { // XXX: Prosody sends headline messages with the // wrong type ('chat'), so we need to filter them out here. - return _converse.log( - `onMessage: Ignoring incoming headline message from JID: ${stanza.getAttribute('from')}`, - Strophe.LogLevel.INFO - ); + return log.info(`onMessage: Ignoring incoming headline message from JID: ${stanza.getAttribute('from')}`); } const bare_forward = sizzle(`message > forwarded[xmlns="${Strophe.NS.FORWARD}"]`, stanza).length; @@ -1163,29 +1155,20 @@ converse.plugins.add('converse-chat', { to_jid = stanza.getAttribute('to'); from_jid = stanza.getAttribute('from'); } else { - return _converse.log( - `onMessage: Ignoring alleged MAM message from ${stanza.getAttribute('from')}`, - Strophe.LogLevel.WARN - ); + return log.warn(`onMessage: Ignoring alleged MAM message from ${stanza.getAttribute('from')}`); } } const from_bare_jid = Strophe.getBareJidFromJid(from_jid); const is_me = from_bare_jid === _converse.bare_jid; if (is_me && to_jid === null) { - return _converse.log( - `Don't know how to handle message stanza without 'to' attribute. ${stanza.outerHTML}`, - Strophe.LogLevel.ERROR - ); + return log.error(`Don't know how to handle message stanza without 'to' attribute. ${stanza.outerHTML}`); } const contact_jid = is_me ? Strophe.getBareJidFromJid(to_jid) : from_bare_jid; const contact = await _converse.api.contacts.get(contact_jid); if (contact === undefined && !_converse.allow_non_roster_messaging) { - _converse.log( - `Blocking messaging with a JID not in our roster because allow_non_roster_messaging is false.`, - Strophe.LogLevel.ERROR - ); - return _converse.log(stanza, Strophe.LogLevel.ERROR); + log.error(`Blocking messaging with a JID not in our roster because allow_non_roster_messaging is false.`); + return log.error(stanza); } // Get chat box, but only create when the message has something to show to the user const has_body = sizzle(`body, encrypted[xmlns="${Strophe.NS.OMEMO}"]`, stanza).length > 0; @@ -1210,7 +1193,7 @@ converse.plugins.add('converse-chat', { // MAM messages are handled in converse-mam. // We shouldn't get MAM messages here because // they shouldn't have a `type` attribute. - _converse.log(`Received a MAM message with type "chat".`, Strophe.LogLevel.WARN); + log.warn(`Received a MAM message with type "chat".`); return true; } _converse.handleMessageStanza(stanza); @@ -1247,9 +1230,7 @@ converse.plugins.add('converse-chat', { if (isString(jid)) { _converse.api.chats.open(jid); } else { - _converse.log( - 'Invalid jid criteria specified for "auto_join_private_chats"', - Strophe.LogLevel.ERROR); + log.error('Invalid jid criteria specified for "auto_join_private_chats"'); } }); /** @@ -1267,10 +1248,7 @@ converse.plugins.add('converse-chat', { /************************ BEGIN Route Handlers ************************/ function openChat (jid) { if (!utils.isValidJID(jid)) { - return _converse.log( - `Invalid JID "${jid}" provided in URL fragment`, - Strophe.LogLevel.WARN - ); + return log.warn(`Invalid JID "${jid}" provided in URL fragment`); } _converse.api.chats.open(jid); } @@ -1312,7 +1290,7 @@ converse.plugins.add('converse-chat', { } const chatbox = _converse.api.chats.get(jids, attrs, true); if (!chatbox) { - _converse.log("Could not open chatbox for JID: "+jids, Strophe.LogLevel.ERROR); + log.error("Could not open chatbox for JID: "+jids); return; } return chatbox; @@ -1324,10 +1302,7 @@ converse.plugins.add('converse-chat', { return _converse.api.chats.get(jid, attrs, true).maybeShow(); })); } - _converse.log( - "chats.create: You need to provide at least one JID", - Strophe.LogLevel.ERROR - ); + log.error("chats.create: You need to provide at least one JID"); return null; }, @@ -1385,7 +1360,7 @@ converse.plugins.add('converse-chat', { ); } const err_msg = "chats.open: You need to provide at least one JID"; - _converse.log(err_msg, Strophe.LogLevel.ERROR); + log.error(err_msg); throw new Error(err_msg); }, diff --git a/src/headless/converse-chatboxes.js b/src/headless/converse-chatboxes.js index cd4c703ca..7d8aa7a06 100644 --- a/src/headless/converse-chatboxes.js +++ b/src/headless/converse-chatboxes.js @@ -9,6 +9,7 @@ import "./converse-emoji"; import converse from "./converse-core"; import { isString } from "lodash"; +import log from "./log"; const { Strophe } = converse.env; @@ -104,7 +105,7 @@ converse.plugins.add('converse-chatboxes', { try { chatbox = new model(attrs, {'collection': _converse.chatboxes}); } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); return null; } await chatbox.initialized; diff --git a/src/headless/converse-core.js b/src/headless/converse-core.js index 5ef917325..cb3423e82 100644 --- a/src/headless/converse-core.js +++ b/src/headless/converse-core.js @@ -15,6 +15,7 @@ import _ from './lodash.noconflict'; import advancedFormat from 'dayjs/plugin/advancedFormat'; import dayjs from 'dayjs'; import i18n from './i18n'; +import log from '@converse/headless/log'; import pluggable from 'pluggable.js/src/pluggable'; import sizzle from 'sizzle'; import u from '@converse/headless/utils/core'; @@ -119,7 +120,7 @@ _converse.Collection = Backbone.Collection.extend({ Object.assign(options, { success, 'error': (m, e) => { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); success() } }) @@ -271,46 +272,12 @@ _converse.default_settings = { whitelisted_plugins: [] }; +const loglevel = _converse.debug ? Strophe.LogLevel.DEBUG : Strophe.LogLevel.INFO; +log.initialize(loglevel); +_converse.log = log.log; -/** - * Logs messages to the browser's developer console. - * Available loglevels are 0 for 'debug', 1 for 'info', 2 for 'warn', - * 3 for 'error' and 4 for 'fatal'. - * When using the 'error' or 'warn' loglevels, a full stacktrace will be - * logged as well. - * @method log - * @private - * @memberOf _converse - * @param { string } message - The message to be logged - * @param { integer } level - The loglevel which allows for filtering of log messages - */ -_converse.log = function (message, level, style='') { - if (level === Strophe.LogLevel.ERROR || level === Strophe.LogLevel.FATAL) { - style = style || 'color: maroon'; - } - if (message instanceof Error) { - message = message.stack; - } else if (_.isElement(message)) { - message = message.outerHTML; - } - const prefix = style ? '%c' : ''; - if (level === Strophe.LogLevel.ERROR) { - u.logger.error(`${prefix} ERROR: ${message}`, style); - } else if (level === Strophe.LogLevel.WARN) { - u.logger.warn(`${prefix} ${(new Date()).toISOString()} WARNING: ${message}`, style); - } else if (level === Strophe.LogLevel.FATAL) { - u.logger.error(`${prefix} FATAL: ${message}`, style); - } else if (_converse.debug) { - if (level === Strophe.LogLevel.DEBUG) { - u.logger.debug(`${prefix} ${(new Date()).toISOString()} DEBUG: ${message}`, style); - } else { - u.logger.info(`${prefix} ${(new Date()).toISOString()} INFO: ${message}`, style); - } - } -}; - -Strophe.log = function (level, msg) { _converse.log(level+' '+msg, level); }; -Strophe.error = function (msg) { _converse.log(msg, Strophe.LogLevel.ERROR); }; +Strophe.log = function (level, msg) { log.log(level+' '+msg, level); }; +Strophe.error = function (msg) { log.log(msg, Strophe.LogLevel.ERROR); }; /** @@ -532,7 +499,7 @@ async function attemptNonPreboundSession (credentials, automatic) { } else if (!_converse.isTestEnv() && window.PasswordCredential) { connect(await getLoginCredentialsFromBrowser()); } else { - _converse.log("attemptNonPreboundSession: Could not find any credentials to log in with", Strophe.LogLevel.WARN); + log.warn("attemptNonPreboundSession: Could not find any credentials to log in with"); } } else if ([_converse.ANONYMOUS, _converse.EXTERNAL].includes(_converse.authentication) && (!automatic || _converse.auto_login)) { connect(); @@ -577,7 +544,7 @@ function connect (credentials) { async function reconnect () { - _converse.log('RECONNECTING: the connection has dropped, attempting to reconnect.'); + log.debug('RECONNECTING: the connection has dropped, attempting to reconnect.'); _converse.setConnectionStatus( Strophe.Status.RECONNECTING, __('The connection has dropped, attempting to reconnect.') @@ -619,7 +586,7 @@ async function onDomainDiscovered (response) { const text = await response.text(); const xrd = (new window.DOMParser()).parseFromString(text, "text/xml").firstElementChild; if (xrd.nodeName != "XRD" || xrd.namespaceURI != "http://docs.oasis-open.org/ns/xri/xrd-1.0") { - return _converse.log("Could not discover XEP-0156 connection methods", Strophe.LogLevel.WARN); + return log.warn("Could not discover XEP-0156 connection methods"); } const bosh_links = sizzle(`Link[rel="urn:xmpp:alt-connections:xbosh"]`, xrd); const ws_links = sizzle(`Link[rel="urn:xmpp:alt-connections:websocket"]`, xrd); @@ -629,9 +596,8 @@ async function onDomainDiscovered (response) { _converse.websocket_url = ws_methods.pop(); _converse.bosh_service_url = bosh_methods.pop(); if (bosh_methods.length === 0 && ws_methods.length === 0) { - _converse.log( - "onDomainDiscovered: neither BOSH nor WebSocket connection methods have been specified with XEP-0156.", - Strophe.LogLevel.WARN + log.warn( + "onDomainDiscovered: neither BOSH nor WebSocket connection methods have been specified with XEP-0156." ); } } @@ -651,13 +617,14 @@ async function discoverConnectionMethods (domain) { try { response = await fetch(url, options); } catch (e) { - _converse.log(`Failed to discover alternative connection methods at ${url}`, Strophe.LogLevel.ERROR); - return _converse.log(e, Strophe.LogLevel.ERROR); + log.error(`Failed to discover alternative connection methods at ${url}`); + log.error(e); + return; } if (response.status >= 200 && response.status < 400) { await onDomainDiscovered(response); } else { - _converse.log("Could not discover XEP-0156 connection methods", Strophe.LogLevel.WARN); + log.warn("Could not discover XEP-0156 connection methods"); } } @@ -794,12 +761,10 @@ function enableCarbons () { .c('enable', {xmlns: Strophe.NS.CARBONS}); _converse.connection.addHandler((iq) => { if (iq.querySelectorAll('error').length > 0) { - _converse.log( - 'An error occurred while trying to enable message carbons.', - Strophe.LogLevel.WARN); + log.warn('An error occurred while trying to enable message carbons.'); } else { _converse.session.save({'carbons_enabled': true}); - _converse.log('Message carbons have been enabled.'); + log.debug('Message carbons have been enabled.'); } }, null, "iq", null, "enablecarbons"); _converse.connection.send(carbons_iq); @@ -850,16 +815,16 @@ async function onConnected (reconnecting) { function setUpXMLLogging () { Strophe.log = function (level, msg) { - _converse.log(msg, level); + log.log(msg, level); }; _converse.connection.xmlInput = function (body) { if (_converse.debug) { - _converse.log(body.outerHTML, Strophe.LogLevel.DEBUG, 'color: darkgoldenrod'); + log.log(body.outerHTML, Strophe.LogLevel.DEBUG, 'color: darkgoldenrod'); } }; _converse.connection.xmlOutput = function (body) { if (_converse.debug) { - _converse.log(body.outerHTML, Strophe.LogLevel.DEBUG, 'color: darkcyan'); + log.log(body.outerHTML, Strophe.LogLevel.DEBUG, 'color: darkcyan'); } }; } @@ -893,7 +858,7 @@ async function finishInitialization () { * @private */ function finishDisconnection () { - _converse.log('DISCONNECTED'); + log.debug('DISCONNECTED'); delete _converse.connection.reconnecting; _converse.connection.reset(); tearDown(); @@ -941,8 +906,8 @@ async function getLoginCredentials () { try { credentials = await fetchLoginCredentials(wait); // eslint-disable-line no-await-in-loop } catch (e) { - _converse.log('Could not fetch login credentials', Strophe.LogLevel.ERROR); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error('Could not fetch login credentials'); + log.error(e); } // If unsuccessful, we wait 2 seconds between subsequent attempts to // fetch the credentials. @@ -1036,7 +1001,7 @@ _converse.initialize = async function (settings, callback) { _converse.locale = i18n.getLocale(settings.i18n, _converse.locales); await i18n.fetchTranslations(_converse); } catch (e) { - _converse.log(e.message, Strophe.LogLevel.FATAL); + log.fatal(e.message); } } @@ -1122,17 +1087,17 @@ _converse.initialize = async function (settings, callback) { * @memberOf _converse */ this.onConnectStatusChanged = function (status, message) { - _converse.log(`Status changed to: ${_converse.CONNECTION_STATUS[status]}`); + log.debug(`Status changed to: ${_converse.CONNECTION_STATUS[status]}`); if (status === Strophe.Status.CONNECTED || status === Strophe.Status.ATTACHED) { _converse.setConnectionStatus(status); // By default we always want to send out an initial presence stanza. _converse.send_initial_presence = true; _converse.setDisconnectionCause(); if (_converse.connection.reconnecting) { - _converse.log(status === Strophe.Status.CONNECTED ? 'Reconnected' : 'Reattached'); + log.debug(status === Strophe.Status.CONNECTED ? 'Reconnected' : 'Reattached'); onConnected(true); } else { - _converse.log(status === Strophe.Status.CONNECTED ? 'Connected' : 'Attached'); + log.debug(status === Strophe.Status.CONNECTED ? 'Connected' : 'Attached'); if (_converse.connection.restored) { // No need to send an initial presence stanza when // we're restoring an existing session. @@ -1701,8 +1666,8 @@ _converse.api = { */ send (stanza) { if (!_converse.api.connection.connected()) { - _converse.log("Not sending stanza because we're not connected!", Strophe.LogLevel.WARN); - _converse.log(Strophe.serialize(stanza), Strophe.LogLevel.WARN); + log.warn("Not sending stanza because we're not connected!"); + log.warn(Strophe.serialize(stanza)); return; } if (_.isString(stanza)) { @@ -1844,6 +1809,7 @@ Object.assign(window.converse, { 'Promise': Promise, 'Strophe': Strophe, '_': _, + 'log': log, 'dayjs': dayjs, 'sizzle': sizzle, 'utils': u diff --git a/src/headless/converse-disco.js b/src/headless/converse-disco.js index cdd3cd827..2a4cb0198 100644 --- a/src/headless/converse-disco.js +++ b/src/headless/converse-disco.js @@ -9,6 +9,7 @@ * Converse plugin which add support for XEP-0030: Service Discovery */ import converse from "./converse-core"; +import log from "./log"; import sizzle from "sizzle"; const { Backbone, Strophe, $iq, utils, _ } = converse.env; @@ -146,7 +147,7 @@ converse.plugins.add('converse-disco', { try { stanza = await _converse.api.disco.info(this.get('jid'), null); } catch (iq) { - _converse.log(iq, Strophe.LogLevel.ERROR); + log.error(iq); this.waitUntilFeaturesDiscovered.resolve(this); return; } @@ -289,7 +290,7 @@ converse.plugins.add('converse-disco', { _converse.api.trigger('streamFeaturesAdded'); }, error (m, e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } }); } @@ -413,7 +414,7 @@ converse.plugins.add('converse-disco', { if (_converse.stream_features === undefined && !_converse.api.connection.connected()) { // Happens during tests when disco lookups happen asynchronously after teardown. const msg = `Tried to get feature ${name} ${xmlns} but _converse.stream_features has been torn down`; - _converse.log(msg, Strophe.LogLevel.WARN); + log.warn(msg); return; } return _converse.stream_features.findWhere({'name': name, 'xmlns': xmlns}); @@ -573,7 +574,7 @@ converse.plugins.add('converse-disco', { if (_converse.disco_entities === undefined && !_converse.api.connection.connected()) { // Happens during tests when disco lookups happen asynchronously after teardown. const msg = `Tried to look up entity ${jid} but _converse.disco_entities has been torn down`; - _converse.log(msg, Strophe.LogLevel.WARN); + log.warn(msg); return; } const entity = _converse.disco_entities.get(jid); @@ -635,7 +636,7 @@ converse.plugins.add('converse-disco', { if (_converse.disco_entities === undefined && !_converse.api.connection.connected()) { // Happens during tests when disco lookups happen asynchronously after teardown. const msg = `Tried to get feature ${feature} for ${jid} but _converse.disco_entities has been torn down`; - _converse.log(msg, Strophe.LogLevel.WARN); + log.warn(msg); return; } entity = await entity.waitUntilFeaturesDiscovered; @@ -771,14 +772,14 @@ converse.plugins.add('converse-disco', { * // The entity DOES NOT have this identity * } * } - * ).catch(e => _converse.log(e, Strophe.LogLevel.FATAL)); + * ).catch(e => log.error(e)); */ async getIdentity (category, type, jid) { const e = await _converse.api.disco.entities.get(jid, true); if (e === undefined && !_converse.api.connection.connected()) { // Happens during tests when disco lookups happen asynchronously after teardown. const msg = `Tried to look up category ${category} for ${jid} but _converse.disco_entities has been torn down`; - _converse.log(msg, Strophe.LogLevel.WARN); + log.warn(msg); return; } return e.getIdentity(category, type); diff --git a/src/headless/converse-mam.js b/src/headless/converse-mam.js index 090490218..1ce342191 100644 --- a/src/headless/converse-mam.js +++ b/src/headless/converse-mam.js @@ -13,6 +13,7 @@ import "./converse-disco"; import "./converse-rsm"; import { intersection, pick } from 'lodash' import converse from "./converse-core"; +import log from "./log"; import sizzle from "sizzle"; const { Strophe, $iq, dayjs } = converse.env; @@ -131,7 +132,7 @@ converse.plugins.add('converse-mam', { try { await message_handler(message); } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } } @@ -188,14 +189,10 @@ converse.plugins.add('converse-mam', { _converse.onMAMError = function (iq) { if (iq.querySelectorAll('feature-not-implemented').length) { - _converse.log( - "Message Archive Management (XEP-0313) not supported by this server", - Strophe.LogLevel.WARN); + log.warn("Message Archive Management (XEP-0313) not supported by this server"); } else { - _converse.log( - "An error occured while trying to set archiving preferences.", - Strophe.LogLevel.ERROR); - _converse.log(iq); + log.error("An error occured while trying to set archiving preferences."); + log.error(iq); } }; @@ -471,7 +468,7 @@ converse.plugins.add('converse-mam', { const jid = attrs.to || _converse.bare_jid; const supported = await _converse.api.disco.supports(Strophe.NS.MAM, jid); if (!supported) { - _converse.log(`Did not fetch MAM archive for ${jid} because it doesn't support ${Strophe.NS.MAM}`); + log.warn(`Did not fetch MAM archive for ${jid} because it doesn't support ${Strophe.NS.MAM}`); return {'messages': []}; } @@ -513,11 +510,11 @@ converse.plugins.add('converse-mam', { const from = stanza.getAttribute('from') || _converse.bare_jid; if (options.groupchat) { if (from !== options['with']) { - _converse.log(`Ignoring alleged groupchat MAM message from ${stanza.getAttribute('from')}`, Strophe.LogLevel.WARN); + log.warn(`Ignoring alleged groupchat MAM message from ${stanza.getAttribute('from')}`); return true; } } else if (from !== _converse.bare_jid) { - _converse.log(`Ignoring alleged MAM message from ${stanza.getAttribute('from')}`, Strophe.LogLevel.WARN); + log.warn(`Ignoring alleged MAM message from ${stanza.getAttribute('from')}`); return true; } messages.push(stanza); @@ -528,13 +525,13 @@ converse.plugins.add('converse-mam', { const iq_result = await _converse.api.sendIQ(stanza, _converse.message_archiving_timeout, false) if (iq_result === null) { const err_msg = "Timeout while trying to fetch archived messages."; - _converse.log(err_msg, Strophe.LogLevel.ERROR); + log.error(err_msg); error = new _converse.TimeoutError(err_msg); return { messages, error }; } else if (u.isErrorStanza(iq_result)) { - _converse.log("Error stanza received while trying to fetch archived messages", Strophe.LogLevel.ERROR); - _converse.log(iq_result, Strophe.LogLevel.ERROR); + log.error("Error stanza received while trying to fetch archived messages"); + log.error(iq_result); return { messages }; } _converse.connection.deleteHandler(message_handler); diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js index aa21473b3..f6c0298f8 100644 --- a/src/headless/converse-muc.js +++ b/src/headless/converse-muc.js @@ -14,6 +14,7 @@ import "./converse-emoji"; import "./utils/muc"; import { clone, get, intersection, invoke, isElement, isObject, isString, uniq, zipObject } from "lodash"; import converse from "./converse-core"; +import log from "./log"; import u from "./utils/form"; const MUC_ROLE_WEIGHTS = { @@ -199,10 +200,7 @@ converse.plugins.add('converse-muc', { async function openRoom (jid) { if (!u.isValidMUCJID(jid)) { - return _converse.log( - `Invalid JID "${jid}" provided in URL fragment`, - Strophe.LogLevel.WARN - ); + return log.warn(`invalid jid "${jid}" provided in url fragment`); } await _converse.api.waitUntil('roomsAutoJoined'); if (_converse.allow_bookmarks) { @@ -266,10 +264,7 @@ converse.plugins.add('converse-muc', { delete this.occupant; const chatbox = get(this, 'collection.chatbox'); if (!chatbox) { - return _converse.log( - `Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`, - Strophe.LogLevel.ERROR - ); + return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`); } this.listenTo(chatbox.occupants, 'add', this.onOccupantAdded); }, @@ -280,10 +275,7 @@ converse.plugins.add('converse-muc', { this.listenTo(this.occupant, 'destroy', this.onOccupantRemoved); const chatbox = get(this, 'collection.chatbox'); if (!chatbox) { - return _converse.log( - `Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`, - Strophe.LogLevel.ERROR - ); + return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`); } this.stopListening(chatbox.occupants, 'add', this.onOccupantAdded); } @@ -293,10 +285,7 @@ converse.plugins.add('converse-muc', { if (this.get('type') !== 'groupchat') { return; } const chatbox = get(this, 'collection.chatbox'); if (!chatbox) { - return _converse.log( - `Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`, - Strophe.LogLevel.ERROR - ); + return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`); } const nick = Strophe.getResourceFromJid(this.get('from')); this.occupant = chatbox.occupants.findWhere({'nick': nick}); @@ -330,10 +319,7 @@ converse.plugins.add('converse-muc', { if (jid) { vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid}); } else { - _converse.log( - `Could not assign VCard for message because no JID found! msgid: ${this.get('msgid')}`, - Strophe.LogLevel.ERROR - ); + log.error(`Could not assign VCard for message because no JID found! msgid: ${this.get('msgid')}`); return; } } @@ -429,10 +415,7 @@ converse.plugins.add('converse-muc', { async enterRoom () { const conn_status = this.get('connection_status'); - _converse.log( - `${this.get('jid')} initialized with connection_status ${conn_status}`, - Strophe.LogLevel.DEBUG - ); + log.debug(`${this.get('jid')} initialized with connection_status ${conn_status}`); if (conn_status !== converse.ROOMSTATUS.ENTERED) { // We're not restoring a room from cache, so let's clear the potentially stale cache. this.removeNonMembers(); @@ -526,7 +509,7 @@ converse.plugins.add('converse-muc', { // MAM messages are handled in converse-mam. // We shouldn't get MAM messages here because // they shouldn't have a `type` attribute. - _converse.log(`Received a MAM message with type "chat".`, Strophe.LogLevel.WARN); + log.warn(`received a mam message with type "chat".`); return true; } this.onMessage(stanza); @@ -651,7 +634,7 @@ converse.plugins.add('converse-muc', { return this.features.destroy({success, 'error': (m, e) => reject(e)}) }); } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); } return _converse.ChatBox.prototype.close.call(this); }, @@ -851,7 +834,7 @@ converse.plugins.add('converse-muc', { identity = await _converse.api.disco.getIdentity('conference', 'text', this.get('jid')); } catch (e) { // Getting the identity probably failed because this room doesn't exist yet. - return _converse.log(e, Strophe.LogLevel.ERROR); + return log.error(e); } const fields = await _converse.api.disco.getFields(this.get('jid')); this.save({ @@ -1126,15 +1109,15 @@ converse.plugins.add('converse-muc', { if (result === null) { const err_msg = `Error: timeout while fetching ${affiliation} list for MUC ${this.get('jid')}`; const err = new Error(err_msg); - _converse.log(err_msg, Strophe.LogLevel.WARN); - _converse.log(result, Strophe.LogLevel.WARN); + log.warn(err_msg); + log.warn(result); return err; } if (u.isErrorStanza(result)) { const err_msg = `Error: not allowed to fetch ${affiliation} list for MUC ${this.get('jid')}`; const err = new Error(err_msg); - _converse.log(err_msg, Strophe.LogLevel.WARN); - _converse.log(result, Strophe.LogLevel.WARN); + log.warn(err_msg); + log.warn(result); return err; } return u.parseMemberListIQ(result).filter(p => p); @@ -1227,12 +1210,12 @@ converse.plugins.add('converse-muc', { } else if (sizzle(`registration-required[xmlns="${Strophe.NS.STANZAS}"]`, e).length) { err_msg = __("You're not allowed to register in this groupchat because it's members-only."); } - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); return err_msg; } const required_fields = sizzle('field required', iq).map(f => f.parentElement); if (required_fields.length > 1 && required_fields[0].getAttribute('var') !== 'muc#register_roomnick') { - return _converse.log(`Can't register the user register in the groupchat ${jid} due to the required fields`); + return log.error(`Can't register the user register in the groupchat ${jid} due to the required fields`); } try { await _converse.api.sendIQ($iq({ @@ -1250,8 +1233,8 @@ converse.plugins.add('converse-muc', { } else if (sizzle(`bad-request[xmlns="${Strophe.NS.STANZAS}"]`, e).length) { err_msg = __("Can't register your nickname in this groupchat, invalid data form supplied."); } - _converse.log(err_msg); - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(err_msg); + log.error(e); return err_msg; } }, @@ -1517,18 +1500,14 @@ converse.plugins.add('converse-muc', { const original_stanza = stanza; const bare_forward = sizzle(`message > forwarded[xmlns="${Strophe.NS.FORWARD}"]`, stanza).length; if (bare_forward) { - return _converse.log( - 'onMessage: Ignoring unencapsulated forwarded groupchat message', - Strophe.LogLevel.WARN - ); + return log.warn('onMessage: Ignoring unencapsulated forwarded groupchat message'); } const is_carbon = u.isCarbonMessage(stanza); if (is_carbon) { // XEP-280: groupchat messages SHOULD NOT be carbon copied, so we're discarding it. - return _converse.log( + return log.warn( 'onMessage: Ignoring XEP-0280 "groupchat" message carbon, '+ - 'according to the XEP groupchat messages SHOULD NOT be carbon copied', - Strophe.LogLevel.WARN + 'according to the XEP groupchat messages SHOULD NOT be carbon copied' ); } const is_mam = u.isMAMMessage(stanza); @@ -1537,10 +1516,7 @@ converse.plugins.add('converse-muc', { const selector = `[xmlns="${Strophe.NS.MAM}"] > forwarded[xmlns="${Strophe.NS.FORWARD}"] > message`; stanza = sizzle(selector, stanza).pop(); } else { - return _converse.log( - `onMessage: Ignoring alleged MAM groupchat message from ${stanza.getAttribute('from')}`, - Strophe.LogLevel.WARN - ); + return log.warn(`onMessage: Ignoring alleged MAM groupchat message from ${stanza.getAttribute('from')}`); } } @@ -2097,9 +2073,7 @@ converse.plugins.add('converse-muc', { } else if (isObject(groupchat)) { _converse.api.rooms.open(groupchat.jid, clone(groupchat)); } else { - _converse.log( - 'Invalid groupchat criteria specified for "auto_join_rooms"', - Strophe.LogLevel.ERROR); + log.error('Invalid groupchat criteria specified for "auto_join_rooms"'); } }); /** @@ -2256,7 +2230,7 @@ converse.plugins.add('converse-muc', { await _converse.api.waitUntil('chatBoxesFetched'); if (jids === undefined) { const err_msg = 'rooms.open: You need to provide at least one JID'; - _converse.log(err_msg, Strophe.LogLevel.ERROR); + log.error(err_msg); throw(new TypeError(err_msg)); } else if (isString(jids)) { const room = await _converse.api.rooms.create(jids, attrs); diff --git a/src/headless/converse-ping.js b/src/headless/converse-ping.js index 392ab14e3..cc74d5a09 100644 --- a/src/headless/converse-ping.js +++ b/src/headless/converse-ping.js @@ -10,6 +10,8 @@ * as specified in XEP-0199 XMPP Ping. */ import converse from "./converse-core"; +import log from "./log"; + const { Strophe, $iq } = converse.env; const u = converse.env.utils; @@ -104,13 +106,13 @@ converse.plugins.add('converse-ping', { const result = await _converse.api.sendIQ(iq, 10000, false); if (result === null) { - _converse.log(`Timeout while pinging ${jid}`, Strophe.LogLevel.WARN); + log.warn(`Timeout while pinging ${jid}`); if (jid === Strophe.getDomainFromJid(_converse.bare_jid)) { _converse.api.connection.reconnect(); } } else if (u.isErrorStanza(result)) { - _converse.log(`Error while pinging ${jid}`, Strophe.LogLevel.ERROR); - _converse.log(result, Strophe.LogLevel.ERROR); + log.error(`Error while pinging ${jid}`); + log.error(result); } return true; } diff --git a/src/headless/converse-pubsub.js b/src/headless/converse-pubsub.js index b5db241b4..d2bc4a3d0 100644 --- a/src/headless/converse-pubsub.js +++ b/src/headless/converse-pubsub.js @@ -8,6 +8,7 @@ */ import "./converse-disco"; import converse from "./converse-core"; +import log from "./log"; const { Strophe, $iq } = converse.env; @@ -68,8 +69,8 @@ converse.plugins.add('converse-pubsub', { Object.keys(options).forEach(k => stanza.c('field', {'var': k}).c('value').t(options[k]).up().up()); } else { - _converse.log(`_converse.api.publish: ${jid} does not support #publish-options, `+ - `so we didn't set them even though they were provided.`) + log.warn(`_converse.api.publish: ${jid} does not support #publish-options, `+ + `so we didn't set them even though they were provided.`) } } try { @@ -83,10 +84,7 @@ converse.plugins.add('converse-pubsub', { // met. We re-publish but without publish-options. const el = stanza.nodeTree; el.querySelector('publish-options').outerHTML = ''; - _converse.log( - `PubSub: Republishing without publish options. ${el.outerHTML}`, - Strophe.LogLevel.WARN - ); + log.warn(`PubSub: Republishing without publish options. ${el.outerHTML}`); _converse.api.sendIQ(el); } else { throw iq; diff --git a/src/headless/converse-roster.js b/src/headless/converse-roster.js index d77c624ca..1a9ad7980 100644 --- a/src/headless/converse-roster.js +++ b/src/headless/converse-roster.js @@ -8,6 +8,7 @@ */ import "@converse/headless/converse-status"; import converse from "@converse/headless/converse-core"; +import log from "./log"; const { Backbone, Strophe, $iq, $pres, dayjs, sizzle, _ } = converse.env; const u = converse.env.utils; @@ -108,7 +109,7 @@ converse.plugins.add('converse-roster', { await _converse.roster.fetchRosterContacts(); _converse.api.trigger('rosterContactsFetched'); } catch (reason) { - _converse.log(reason, Strophe.LogLevel.ERROR); + log.error(reason); } finally { _converse.sendInitialPresence(); } @@ -424,7 +425,7 @@ converse.plugins.add('converse-roster', { }); }); if (u.isErrorObject(result)) { - _converse.log(result, Strophe.LogLevel.ERROR); + log.error(result); // Force a full roster refresh _converse.session.set('roster_cached', false) this.data.save('version', undefined); @@ -516,7 +517,7 @@ converse.plugins.add('converse-roster', { try { await this.sendContactAddIQ(jid, name, groups); } catch (e) { - _converse.log(e, Strophe.LogLevel.ERROR); + log.error(e); alert(__('Sorry, there was an error while trying to add %1$s as a contact.', name || jid)); return e; } @@ -568,9 +569,8 @@ converse.plugins.add('converse-roster', { // attribute (i.e., implicitly from the bare JID of the user's // account) or it has a 'from' attribute whose value matches the // user's bare JID . - _converse.log( - `Ignoring roster illegitimate roster push message from ${iq.getAttribute('from')}`, - Strophe.LogLevel.WARN + log.warn( + `Ignoring roster illegitimate roster push message from ${iq.getAttribute('from')}` ); return; } @@ -581,12 +581,12 @@ converse.plugins.add('converse-roster', { const items = sizzle(`item`, query); if (items.length > 1) { - _converse.log(iq, Strophe.LogLevel.ERROR); + log.error(iq); throw new Error('Roster push query may not contain more than one "item" element.'); } if (items.length === 0) { - _converse.log(iq, Strophe.LogLevel.WARN); - _converse.log('Received a roster push stanza without an "item" element.', Strophe.LogLevel.WARN); + log.warn(iq); + log.warn('Received a roster push stanza without an "item" element.'); return; } this.updateContact(items.pop()); @@ -628,8 +628,9 @@ converse.plugins.add('converse-roster', { } } else if (!u.isServiceUnavailableError(iq)) { // Some unknown error happened, so we will try to fetch again if the page reloads. - _converse.log(iq, Strophe.LogLevel.ERROR); - return _converse.log("Error while trying to fetch roster from the server", Strophe.LogLevel.ERROR); + log.error(iq); + log.error("Error while trying to fetch roster from the server"); + return; } _converse.session.save('roster_cached', true); /** diff --git a/src/headless/converse-smacks.js b/src/headless/converse-smacks.js index 321088716..f9352a1a8 100644 --- a/src/headless/converse-smacks.js +++ b/src/headless/converse-smacks.js @@ -10,8 +10,9 @@ * Converse.js plugin which adds support for XEP-0198: Stream Management */ import converse from "./converse-core"; +import log from "./log"; -const { Strophe, } = converse.env; +const { Strophe } = converse.env; const u = converse.env.utils; @@ -50,7 +51,7 @@ converse.plugins.add('converse-smacks', { if (delta < 0) { const err_msg = `New reported stanza count lower than previous. `+ `New: ${handled} - Previous: ${last_known_handled}` - _converse.log(err_msg, Strophe.LogLevel.ERROR); + log.error(err_msg); } const unacked_stanzas = _converse.session.get('unacked_stanzas'); if (delta > unacked_stanzas.length) { @@ -59,7 +60,7 @@ converse.plugins.add('converse-smacks', { `Reported Acknowledged Count: ${delta} -`+ `Unacknowledged Stanza Count: ${unacked_stanzas.length} -`+ `New: ${handled} - Previous: ${last_known_handled}` - _converse.log(err_msg, Strophe.LogLevel.ERROR); + log.error(err_msg); } _converse.session.save({ 'num_stanzas_handled_by_server': handled, @@ -125,11 +126,11 @@ converse.plugins.add('converse-smacks', { // // After resource binding, sendEnableStanza will be called // based on the afterResourceBinding event. - _converse.log('Could not resume previous SMACKS session, session id not found. '+ - 'A new session will be established.', Strophe.LogLevel.WARN); + log.warn('Could not resume previous SMACKS session, session id not found. '+ + 'A new session will be established.'); } else { - _converse.log('Failed to enable stream management', Strophe.LogLevel.ERROR); - _converse.log(el.outerHTML, Strophe.LogLevel.ERROR); + log.error('Failed to enable stream management'); + log.error(el.outerHTML); } resetSessionData(); /** @@ -224,7 +225,7 @@ converse.plugins.add('converse-smacks', { function onStanzaSent (stanza) { if (!_converse.session) { - _converse.log('No _converse.session!', Strophe.LogLevel.WARN); + log.warn('No _converse.session!'); return; } if (!_converse.session.get('smacks_enabled')) { diff --git a/src/headless/log.js b/src/headless/log.js new file mode 100644 index 000000000..a350fcaf8 --- /dev/null +++ b/src/headless/log.js @@ -0,0 +1,87 @@ +import * as strophe from 'strophe.js/src/core'; +import { get, isElement } from 'lodash'; + +const Strophe = strophe.default.Strophe; + +const logger = Object.assign({ + 'debug': get(console, 'log') ? console.log.bind(console) : function noop () {}, + 'error': get(console, 'log') ? console.log.bind(console) : function noop () {}, + 'info': get(console, 'log') ? console.log.bind(console) : function noop () {}, + 'warn': get(console, 'log') ? console.log.bind(console) : function noop () {} +}, console); + + +/** + * The log namespace + * @namespace log + */ +const log = { + + /** + * Initialize the logger by setting the loglevel + * @method log#initialize + * @param { string } message - The message to be logged + * @param { integer } level - The loglevel which allows for filtering of log messages + */ + initialize (loglevel) { + this.loglevel = loglevel; + }, + + /** + * Logs messages to the browser's developer console. + * Available loglevels are 0 for 'debug', 1 for 'info', 2 for 'warn', + * 3 for 'error' and 4 for 'fatal'. + * When using the 'error' or 'warn' loglevels, a full stacktrace will be + * logged as well. + * @method log#log + * @param { string } message - The message to be logged + * @param { integer } level - The loglevel which allows for filtering of log messages + */ + log (message, level, style='') { + if (level === Strophe.LogLevel.ERROR || level === Strophe.LogLevel.FATAL) { + style = style || 'color: maroon'; + } else if (level === Strophe.LogLevel.DEBUG) { + style = style || 'color: green'; + } + + if (message instanceof Error) { + message = message.stack; + } else if (isElement(message)) { + message = message.outerHTML; + } + const prefix = style ? '%c' : ''; + if (level === Strophe.LogLevel.ERROR) { + logger.error(`${prefix} ERROR: ${message}`, style); + } else if (level === Strophe.LogLevel.WARN) { + logger.warn(`${prefix} ${(new Date()).toISOString()} WARNING: ${message}`, style); + } else if (level === Strophe.LogLevel.FATAL) { + logger.error(`${prefix} FATAL: ${message}`, style); + } else if (this.loglevel === Strophe.LogLevel.DEBUG && level === Strophe.LogLevel.DEBUG) { + logger.debug(`${prefix} ${(new Date()).toISOString()} DEBUG: ${message}`, style); + } else if (this.loglevel === Strophe.LogLevel.INFO) { + logger.info(`${prefix} ${(new Date()).toISOString()} INFO: ${message}`, style); + } + }, + + debug (message) { + this.log(message, Strophe.LogLevel.DEBUG); + }, + + error (message) { + this.log(message, Strophe.LogLevel.ERROR); + }, + + info (message) { + this.log(message, Strophe.LogLevel.INFO); + }, + + warn (message) { + this.log(message, Strophe.LogLevel.WARN); + }, + + fatal (message) { + this.log(message, Strophe.LogLevel.FATAL); + } +} + +export default log; diff --git a/src/headless/utils/core.js b/src/headless/utils/core.js index a5be51227..3919f18ab 100644 --- a/src/headless/utils/core.js +++ b/src/headless/utils/core.js @@ -9,6 +9,7 @@ import * as strophe from 'strophe.js/src/core'; import Backbone from "backbone"; import _ from "../lodash.noconflict"; +import log from "@converse/headless/log"; import sizzle from "sizzle"; const Strophe = strophe.default.Strophe; @@ -19,12 +20,6 @@ const Strophe = strophe.default.Strophe; */ const u = {}; -u.logger = Object.assign({ - 'debug': _.get(console, 'log') ? console.log.bind(console) : function noop () {}, - 'error': _.get(console, 'log') ? console.log.bind(console) : function noop () {}, - 'info': _.get(console, 'log') ? console.log.bind(console) : function noop () {}, - 'warn': _.get(console, 'log') ? console.log.bind(console) : function noop () {} -}, console); u.isTagEqual = function (stanza, name) { if (stanza.nodeTree) { @@ -643,7 +638,7 @@ u.waitUntil = function (func, max_wait=300, check_delay=3) { const max_wait_timeout = setTimeout(() => { clearTimers(max_wait_timeout, interval); const err_msg = 'Wait until promise timed out'; - u.logger.error(err_msg); + log.error(err_msg); promise.reject(new Error(err_msg)); }, max_wait);