Skip to content
This repository has been archived by the owner on Dec 4, 2018. It is now read-only.

Commit

Permalink
Handle and report invalid notify(err) argument. Fixes #110.
Browse files Browse the repository at this point in the history
notify(err…) now catches and reports the case where err=null|undefined|0|true|false.

An error-level log is printed and Error is constructed and sent to Bugsnag
with the offending parameter. All of the arguments are captured and sent
in the report's metadata too, to help provide context for when this happens.
  • Loading branch information
bengourley committed Sep 6, 2017
1 parent 986bfaa commit c539c53
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/bugsnag.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ Bugsnag.notify = function(error, options, cb) {
if (!options) {
options = {};
}
if ((!error && typeof error !== "string") || error === true) {
Configuration.logger.error("Bugsnag.notify(error…) accepts an object or a string but was called with '" + error + "'");
options.metaData = {
"notify() arguments": JSON.stringify([].map.call(arguments, function(arg) { return arg }), Utils.sensibleReplacer, 2)
};
error = new Error("[Bugsnag] Bugsnag.notify(error…) accepts an object or a string but was called with '" + error + "'");
}
if (!Bugsnag.shouldNotify()) {
if (cb) {
if (!Configuration.apiKey) {
Expand Down
10 changes: 10 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@ var Utils = {

_filterHandler: function() {
return '[FILTERED]';
},

// this custom replacer (for use in JSON.stringify(obj, replacer, spaces)) is implemented to
// ensure values such as `undefined` and `Function` get serialized in a sensible way. Otherwise
// `Function`s get removed and `undefined` gets converted to null, which would be a misleading
// representation of what was passed to this function.
sensibleReplacer: function (key, value) {
if (value === undefined) return "undefined";
if (typeof value === "function") return value.name ? ("[function " + value.name + "()]") : "[anonymous function]";
return value;
}
};

Expand Down
26 changes: 26 additions & 0 deletions test/notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,30 @@ describe("Notification", function() {
});
});
});

describe("bad input", function() {
it("notify(err) should handle bad input", function () {
should.not.throw(function () {
Bugsnag.notify(null);
});
should.not.throw(function () {
Bugsnag.notify(undefined);
});
should.not.throw(function () {
Bugsnag.notify(0);
});
should.not.throw(function () {
Bugsnag.notify([]);
});
should.not.throw(function () {
Bugsnag.notify(new Date());
});
should.not.throw(function () {
Bugsnag.notify(false);
});
should.not.throw(function () {
Bugsnag.notify(true);
});
});
});
});
6 changes: 6 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,10 @@ describe("utils", function() {
data.password.should.equal('[FILTERED]')
});
});

describe("sensibleReplacer", function () {
JSON.stringify({ a: undefined }, Utils.sensibleReplacer).should.equal("{\"a\":\"undefined\"}");
JSON.stringify({ a: function () {} }, Utils.sensibleReplacer).should.equal("{\"a\":\"[function a()]\"}");
JSON.stringify({ a: [ function () {} ] }, Utils.sensibleReplacer).should.equal("{\"a\":[\"[anonymous function]\"]}");
});
});

0 comments on commit c539c53

Please sign in to comment.