diff --git a/src/__tests__/ConsoleLogger-test.js b/src/__tests__/ConsoleLogger-test.js index 5b4f5d1..e637143 100644 --- a/src/__tests__/ConsoleLogger-test.js +++ b/src/__tests__/ConsoleLogger-test.js @@ -93,6 +93,25 @@ describe('createConsoleLogger', () => { expect(infoSpy).not.toHaveBeenCalled(); expect(warnSpy).not.toHaveBeenCalled(); }); + + it('does not throw an error if console is undefined or null', () => { + // see comments in ConsoleLogger.js + const oldConsole = console; + try { + console = null; // eslint-disable-line no-global-assign + logger.debug('x'); + logger.info('x'); + logger.warn('x'); + logger.error('x'); + console = undefined; // eslint-disable-line no-global-assign + logger.debug('x'); + logger.info('x'); + logger.warn('x'); + logger.error('x'); + } finally { + console = oldConsole; // eslint-disable-line no-global-assign + } + }); }); }); }); diff --git a/src/consoleLogger.js b/src/consoleLogger.js index 7fc9126..78b9f3a 100644 --- a/src/consoleLogger.js +++ b/src/consoleLogger.js @@ -2,6 +2,10 @@ // If no minimum level is specified, all messages will be logged. Setting the level to "none" // disables all logging. +// Note that the global console variable is not guaranteed to be defined at all times in all +// browsers, so this implementation checks for its existence at the time a message is logged. +// See: https://www.beyondjava.net/console-log-surprises-with-internet-explorer-11-and-edge + export default function createConsoleLogger(level, maybePrefix) { const allLevels = ['debug', 'info', 'warn', 'error']; let prefix; @@ -21,17 +25,20 @@ export default function createConsoleLogger(level, maybePrefix) { const logger = {}; - function log(levelIndex, outputFn, msg) { - if (levelIndex >= minLevelIndex) { - const levelName = levelIndex < allLevels.length ? allLevels[levelIndex] : '?'; - outputFn(prefix + '[' + levelName + '] ' + msg); + function log(levelIndex, methodName, msg) { + if (levelIndex >= minLevelIndex && console) { + const method = console[methodName]; + if (method) { + const levelName = levelIndex < allLevels.length ? allLevels[levelIndex] : '?'; + method.call(console, prefix + '[' + levelName + '] ' + msg); + } } } - logger.debug = msg => log(0, console.log, msg); // eslint-disable-line no-console - logger.info = msg => log(1, console.info, msg); // eslint-disable-line no-console - logger.warn = msg => log(2, console.warn, msg); // eslint-disable-line no-console - logger.error = msg => log(3, console.error, msg); // eslint-disable-line no-console + logger.debug = msg => log(0, 'log', msg); // eslint-disable-line no-console + logger.info = msg => log(1, 'info', msg); // eslint-disable-line no-console + logger.warn = msg => log(2, 'warn', msg); // eslint-disable-line no-console + logger.error = msg => log(3, 'error', msg); // eslint-disable-line no-console return logger; }