diff --git a/lib/winston/common.js b/lib/winston/common.js index fc210bbd5..3221359bd 100644 --- a/lib/winston/common.js +++ b/lib/winston/common.js @@ -22,6 +22,7 @@ var util = require('util'), // for each of those levels. // exports.setLevels = function (target, past, current, isDefault) { + var self = this; if (past) { Object.keys(past).forEach(function (level) { delete target[level]; @@ -38,6 +39,17 @@ exports.setLevels = function (target, past, current, isDefault) { // e.g. target.log('info', msg) <=> target.info(msg) // Object.keys(target.levels).forEach(function (level) { + + // TODO Refactor logging methods into a different object to avoid name clashes + if (level === 'log') { + throw new Error('There cannot be a log level named "log" as it will clash with the method "log"'); + } + + // TODO Discuss the right approach here + if (target[level]) { + console.warn('Logging method "' + level + '" overrides an existing property. Consider level renaming.'); + } + target[level] = function (msg) { // build argument list (level, msg, ... [string interpolate], [{metadata}], [callback]) var args = [level].concat(Array.prototype.slice.call(arguments)); diff --git a/test/logger-levels-test.js b/test/logger-levels-test.js index e165c63ef..07fc717db 100644 --- a/test/logger-levels-test.js +++ b/test/logger-levels-test.js @@ -110,7 +110,57 @@ vows.describe('winston/logger/levels').addBatch({ "should join and have a meta object": function (transport, level, msg, meta) { assert.strictEqual(msg, 'test message first second'); assert.deepEqual(meta, {number: 123}); - } + } + }, + "when custom levels are set": { + "should not fail with 'RangeError: Maximum call stack size exceeded": function (logger) { + var that = this; + + // Logging levels + var customLevels = { + levels: { + none: 0, + log: 1, + } + }; + + var logger = winston.loggers.add('hello243', { }); + try { + logger.setLevels(customLevels.levels); + } catch (e) { + assert.equal('Error', e.name); + } + try { + logger.log('none', 'hi', function (err) { + assert.ifError(err); + }); + } catch (e) { + assert.ifError(e); + } + }, + "should warn if logging level overrides a method": function (logger) { + var that = this; + + // Logging levels + var customLevels = { + levels: { + none: 0, + extend: 1, + } + }; + + // TODO Find a better way to do this + var oldWarn = console.warn; + console.warn = function (x) { + assert.equal('Logging method "extend" overrides ' + + 'an existing property. Consider level renaming.', x); + console.warn = oldWarn; + }; + + var logger = winston.loggers.add('hello243', { }); + logger.setLevels(customLevels.levels); + + } } } }).export(module);