Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not modify Error or Date objects when logging. Fixes #610 #703

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions lib/winston/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,25 @@ exports.clone = function (obj) {
//
// We only need to clone reference types (Object)
//
var copy = {};

if (obj instanceof Error) {
return obj;
// With potential custom Error objects, this might not be exactly correct,
// but probably close-enough for purposes of this lib.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is not going to cut it for winston, sorry. Do this:

copy = new Error(obj.message);
Object.getOwnPropertyNames(obj).forEach(function (key) {
  copy[key] = obj[key];
}); 

return copy;

copy = new Error(obj.message);
for (var i in obj) {
copy[i] = obj[i];
}

return copy;
}
else if (!(obj instanceof Object)) {
return obj;
}
else if (obj instanceof Date) {
return obj;
return new Date(obj.getTime());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome.

}

var copy = {};
for (var i in obj) {
if (Array.isArray(obj[i])) {
copy[i] = obj[i].slice(0);
Expand Down
36 changes: 36 additions & 0 deletions test/transports/file-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,42 @@ vows.describe('winston/transports/file').addBatch({
assert.isTrue(true);
}
}
}).addBatch({
"Error object in metadata #610": {
topic: function () {
var myErr = new Error("foo");

fileTransport.log('info', 'test message', myErr, this.callback.bind(this, null, myErr));
},
"should not be modified": function (err, myErr) {
assert.equal(myErr.message, "foo");
// Not sure if this is the best possible way to check if additional props appeared
assert.deepEqual(Object.getOwnPropertyNames(myErr), Object.getOwnPropertyNames(new Error("foo")));
}
}
}).addBatch({
"Date object in metadata": {
topic: function () {
var obj = new Date(1000);

fileTransport.log('info', 'test message', obj, this.callback.bind(this, null, obj));
},
"should not be modified": function (err, obj) {
// Not sure if this is the best possible way to check if additional props appeared
assert.deepEqual(Object.getOwnPropertyNames(obj), Object.getOwnPropertyNames(new Date()));
}
}
}).addBatch({
"Plain object in metadata": {
topic: function () {
var obj = { message: "foo" };

fileTransport.log('info', 'test message', obj, this.callback.bind(this, null, obj));
},
"should not be modified": function (err, obj) {
assert.deepEqual(obj, { message: "foo" });
}
}
}).addBatch({
"An instance of the File Transport": transport(winston.transports.File, {
filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log')
Expand Down
30 changes: 30 additions & 0 deletions test/winston-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,36 @@ vows.describe('winston').addBatch({
assert.isTrue(typeof winston[key] === 'undefined');
});
}
},
"the clone() method": {
"with Error object": {
topic: function () {
var original = new Error("foo");
original.name = "bar";

var copy = winston.clone(original);

return { original: original, copy: copy };
},
"should clone the value": function (result) {
assert.notEqual(result.original, result.copy);
assert.equal(result.original.message, result.copy.message);
assert.equal(result.original.name, result.copy.name);
}
},
"with Date object": {
topic: function () {
var original = new Date(1000);

var copy = winston.clone(original);

return { original: original, copy: copy };
},
"should clone the value": function (result) {
assert.notEqual(result.original, result.copy);
assert.equal(result.original.getTime(), result.copy.getTime());
}
}
}
}
}).export(module);