From 8350f52b9d25ddfa6489faddc02433031c2682ea Mon Sep 17 00:00:00 2001 From: Avital Oliver Date: Wed, 10 Apr 2013 21:13:55 -0700 Subject: [PATCH] Improve Meteor.Error - Capture stack traces on server (Meteor.Error objects are only created on the client, not thrown) - Set a message - Improve inheritence pattern Before: (note that the stack trace shows the line in which Meteor.Error is defined, not where it got thrown) === - exception - message Error at app/packages/livedata/livedata_common.js:143:26 at /private/var/folders/tp/sc9b5w7n2qndz3chpmktwy_w0000gn/T/meteor-test-runikymph/.meteor/local/build/server/server.js:282:7 at Array.forEach (native) at Function._.each._.forEach (/Users/avital/meteor/dev_bundle/lib/node_modules/underscore/underscore.js:79:11) at run (/private/var/folders/tp/sc9b5w7n2qndz3chpmktwy_w0000gn/T/meteor-test-runikymph/.meteor/local/build/server/server.js:227:7) After: === - exception - message User validation failed [403] Error: User validation failed [403] at app/packages/accounts-base/accounts_server.js:164:13 at Array.forEach (native) at Function._.each._.forEach (app/packages/underscore/underscore.js:79:11) at Object.Accounts.insertUserDoc (app/packages/accounts-base/accounts_server.js:162:5) at Object.Accounts.updateOrCreateUserFromExternalService (app/packages/accounts-base/accounts_server.js:264:21) at null.func (app/packages/accounts-base/accounts_tests.js:18:28) at app/packages/tinytest/tinytest.js:299:16 at app/packages/meteor/timers.js:54:36 at _.extend.withValue (app/packages/meteor/dynamics_nodejs.js:31:17) at f (app/packages/meteor/timers.js:12:51) --- packages/livedata/livedata_common.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/livedata/livedata_common.js b/packages/livedata/livedata_common.js index c9af4b81dc..a919cd8cae 100644 --- a/packages/livedata/livedata_common.js +++ b/packages/livedata/livedata_common.js @@ -122,6 +122,16 @@ Meteor._CurrentInvocation = new Meteor.EnvironmentVariable; Meteor.Error = function (error, reason, details) { var self = this; + // Meteor.Error is defined on both client and server, but it only + // has a stack trace on the server. Luckily, Error.captureStackTrace + // achieves this on V8. Googling and experimentation found no way to + // capture stack traces on all browsers, so it seems that this is + // not a viable general pattern for creating custom Error + // classes. If we need to do that, we'd probably be best off setting + // a 'type' property on the Error object instead. + if (Error.captureStackTrace) + Error.captureStackTrace(self, Meteor.Error); + // Currently, a numeric code, likely similar to a HTTP code (eg, // 404, 500). That is likely to change though. self.error = error; @@ -138,6 +148,21 @@ Meteor.Error = function (error, reason, details) { // never expect this to be shown to end users, only developers, so // it doesn't need to be pretty.) self.details = details; + + // This is what gets displayed at the top of a stack trace. Current + // format is "[404]" (if no reason is set) or "File not found [404]" + if (self.reason) + self.message = self.reason + ' [' + self.error + ']'; + else + self.message = '[' + self.error + ']'; }; -Meteor.Error.prototype = new Error; +// http://davidshariff.com/blog/javascript-inheritance-patterns/ +var inherits = function (child, parent) { + var tmp = function () {}; + tmp.prototype = parent.prototype; + child.prototype = new tmp; + child.prototype.constructor = child; +}; + +inherits(Meteor.Error, Error); \ No newline at end of file