Files
meteor/packages/meteor/errors.js
2024-01-03 16:21:32 -03:00

97 lines
3.8 KiB
JavaScript

// Makes an error subclass which properly contains a stack trace in most
// environments. constructor can set fields on `this` (and should probably set
// `message`, which is what gets displayed at the top of a stack trace).
//
Meteor.makeErrorType = function (name, constructor) {
var errorClass = function (/*arguments*/) {
// Ensure we get a proper stack trace in most Javascript environments
if (Error.captureStackTrace) {
// V8 environments (Chrome and Node.js)
Error.captureStackTrace(this, errorClass);
} else {
// Borrow the .stack property of a native Error object.
this.stack = new Error().stack;
}
// Safari magically works.
constructor.apply(this, arguments);
this.errorType = name;
};
Meteor._inherits(errorClass, Error);
return errorClass;
};
// This should probably be in the livedata package, but we don't want
// to require you to use the livedata package to get it. Eventually we
// should probably rename it to DDP.Error and put it back in the
// 'livedata' package (which we should rename to 'ddp' also.)
//
// Note: The DDP server assumes that Meteor.Error EJSON-serializes as an object
// containing 'error' and optionally 'reason' and 'details'.
// The DDP client manually puts these into Meteor.Error objects. (We don't use
// EJSON.addType here because the type is determined by location in the
// protocol, not text on the wire.)
/**
* @summary This class represents a symbolic error thrown by a method.
* @locus Anywhere
* @class
* @param {String} error A string code uniquely identifying this kind of error.
* This string should be used by callers of the method to determine the
* appropriate action to take, instead of attempting to parse the reason
* or details fields.
*
* For legacy reasons, some built-in Meteor functions such as `check` throw
* errors with a number in this field.
*
* @param {String} [reason] Optional. A short human-readable summary of the
* error, like 'Not Found'.
* @param {String} [details] Optional. Additional information about the error,
* like a textual stack trace.
*/
Meteor.Error = Meteor.makeErrorType(
"Meteor.Error",
function (error, reason, details) {
var self = this;
// Newer versions of DDP use this property to signify that an error
// can be sent back and reconstructed on the calling client.
self.isClientSafe = true;
// String code uniquely identifying this kind of error.
self.error = error;
// Optional: A short human-readable summary of the error. Not
// intended to be shown to end users, just developers. ("Not Found",
// "Internal Server Error")
self.reason = reason;
// Optional: Additional information about the error, say for
// debugging. It might be a (textual) stack trace if the server is
// willing to provide one. The corresponding thing in HTTP would be
// the body of a 404 or 500 response. (The difference is that we
// 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 is basically data and is sent over DDP, so you should be able to
// properly EJSON-clone it. This is especially important because if a
// Meteor.Error is thrown through a Future, the error, reason, and details
// properties become non-enumerable so a standard Object clone won't preserve
// them and they will be lost from DDP.
Meteor.Error.prototype.clone = function () {
var self = this;
return new Meteor.Error(self.error, self.reason, self.details);
};