#if COPYRIGHT
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//------------------------------------------------------------------------------
#endif
Error.__typeName = 'Error';
Error.__class = true;
Error.create = function(message, errorInfo) {
/// Use this method to create a new error.
/// The error message.
///
/// A plain JavaScript object that contains extended information about the error.
/// The object should have a 'name' field that contains a string that identifies the error
/// and any additional fields that are necessary to fully describe the error.
///
/// An Error object.
// If message string can be converted to a number, IE sets e.message to the number, not the string.
// Workaround this issue by explicitly setting e.message to the string.
var err = new Error(message);
err.message = message;
if (errorInfo) {
for (var v in errorInfo) {
err[v] = errorInfo[v];
}
}
err.popStackFrame();
return err;
}
// The ArgumentException ctor in .NET has the message *before* paramName. This
// is inconsistent with all the other Argument*Exception ctors in .NET.
// We feel the paramName is more important than the message, and we want all our
// argument errors to be consistent, so our Error.argument() takes the paramName
// before the message. This is inconsistent with .NET, but overall we feel
// it is the better design.
Error.argument = function(paramName, message) {
///
/// Creates an ArgumentException with a specified error message
/// and the name of the parameter that caused this exception.
///
///
/// The name of the parameter that caused the exception.
///
///
/// A message that describes the error.
///
/// An Error instance that represents an ArgumentException.
var displayMessage = "Sys.ArgumentException: " + (message ? message : Sys.Res.argument);
if (paramName) {
displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
}
var err = Error.create(displayMessage, { name: "Sys.ArgumentException", paramName: paramName });
err.popStackFrame();
return err;
}
Error.argumentNull = function(paramName, message) {
///
/// Creates an ArgumentNullException with a specified error message
/// and the name of the parameter that caused this exception.
///
///
/// The name of the parameter that caused the exception.
///
///
/// A message that describes the error.
///
/// An Error instance that represents an ArgumentNullException.
var displayMessage = "Sys.ArgumentNullException: " + (message ? message : Sys.Res.argumentNull);
if (paramName) {
displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
}
var err = Error.create(displayMessage, { name: "Sys.ArgumentNullException", paramName: paramName });
err.popStackFrame();
return err;
}
Error.argumentOutOfRange = function(paramName, actualValue, message) {
///
/// Creates an ArgumentOutOfRangeException with a specified error message
/// and the name and actual value of the parameter that caused this exception.
///
///
/// The name of the parameter that caused the exception.
///
///
/// The actual value of the parameter.
///
///
/// A message that describes the error.
///
/// An Error instance that represents an ArgumentOutOfRangeException.
var displayMessage = "Sys.ArgumentOutOfRangeException: " + (message ? message : Sys.Res.argumentOutOfRange);
if (paramName) {
displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
}
// .NET implementation of ArgumentOutOfRangeException does not display actualValue if it is null.
// For parity with .NET, we do not display if actualValue is null or undefined. This is OK,
// since more specific exceptions exist for null and undefined.
if (typeof(actualValue) !== "undefined" && actualValue !== null) {
displayMessage += "\n" + String.format(Sys.Res.actualValue, actualValue);
}
var err = Error.create(displayMessage, {
name: "Sys.ArgumentOutOfRangeException",
paramName: paramName,
actualValue: actualValue
});
err.popStackFrame();
return err;
}
Error.argumentType = function(paramName, actualType, expectedType, message) {
///
/// Creates an ArgumentTypeException with a specified error message
/// and the name, actual type, and expected type of the parameter that
/// caused this exception.
///
///
/// The name of the parameter that caused the exception.
///
///
/// The actual type of the parameter value.
///
///
/// The expected type of the parameter value.
///
///
/// A message that describes the error.
///
/// An Error instance that represents an ArgumentTypeException.
var displayMessage = "Sys.ArgumentTypeException: ";
if (message) {
displayMessage += message;
}
else if (actualType && expectedType) {
displayMessage +=
String.format(Sys.Res.argumentTypeWithTypes, actualType.getName(), expectedType.getName());
}
else {
displayMessage += Sys.Res.argumentType;
}
if (paramName) {
displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
}
var err = Error.create(displayMessage, {
name: "Sys.ArgumentTypeException",
paramName: paramName,
actualType: actualType,
expectedType: expectedType
});
err.popStackFrame();
return err;
}
Error.argumentUndefined = function(paramName, message) {
///
/// Creates an ArgumentUndefinedException with a specified error message
/// and the name of the parameter that caused this exception.
///
///
/// The name of the parameter that caused the exception.
///
///
/// A message that describes the error.
///
/// An Error instance that represents an ArgumentUndefinedException.
var displayMessage = "Sys.ArgumentUndefinedException: " + (message ? message : Sys.Res.argumentUndefined);
if (paramName) {
displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
}
var err = Error.create(displayMessage, { name: "Sys.ArgumentUndefinedException", paramName: paramName });
err.popStackFrame();
return err;
}
Error.format = function(message) {
///
/// Creates a format error.
///
/// The error message.
/// An Error object that represents a FormatException.
var displayMessage = "Sys.FormatException: " + (message ? message : Sys.Res.format);
var err = Error.create(displayMessage, {name: 'Sys.FormatException'});
err.popStackFrame();
return err;
}
Error.invalidOperation = function(message) {
///
/// Creates an invalid operation error.
///
/// The error message.
/// An Error instance that represents an InvalidOperationException.
var displayMessage = "Sys.InvalidOperationException: " + (message ? message : Sys.Res.invalidOperation);
var err = Error.create(displayMessage, {name: 'Sys.InvalidOperationException'});
err.popStackFrame();
return err;
}
Error.notImplemented = function(message) {
///
/// Creates a not implemented error.
///
/// The error message.
/// An Error instance that represents a NotImplementedException.
var displayMessage = "Sys.NotImplementedException: " + (message ? message : Sys.Res.notImplemented);
var err = Error.create(displayMessage, {name: 'Sys.NotImplementedException'});
err.popStackFrame();
return err;
}
Error.parameterCount = function(message) {
///
/// Creates a ParameterCountException with a specified error message.
///
///
/// A message that describes the error.
///
/// An Error instance that represents a ParameterCountException.
var displayMessage = "Sys.ParameterCountException: " + (message ? message : Sys.Res.parameterCount);
var err = Error.create(displayMessage, {name: 'Sys.ParameterCountException'});
err.popStackFrame();
return err;
}
Error.prototype.popStackFrame = function() {
///
/// Updates the fileName and lineNumber fields based on the next frame in the
/// stack trace. Call this method whenever an instance of Error is returned
/// from a function. This makes the fileName and lineNumber reported in the
/// FireFox console point to the location where the exception was thrown, not
/// the location where the instance of Error was created.
///
///
/// function checkParam(param, expectedType) {
/// if (!expectedType.isInstanceOfType(param)) {
/// var e = new Error("invalid type");
/// e.popStackFrame();
/// return e;
/// }
/// }
///
// Example stack frame
// ===================
// Error("test error")@:0
// createError()@http://localhost/app/Error.js:2
// throwError()@http://localhost/app/Error.js:6
// callThrowError()@http://localhost/app/Error.js:10
// @http://localhost/app/Error:js:14
if (typeof(this.stack) === "undefined" || this.stack === null ||
typeof(this.fileName) === "undefined" || this.fileName === null ||
typeof(this.lineNumber) === "undefined" || this.lineNumber === null) {
return;
}
var stackFrames = this.stack.split("\n");
// Find current stack frame. It may not be the first stack frame, since the very
// first frame when the Error is constructed does not correspond to any actual file
// or line number. See example stack frame above.
var currentFrame = stackFrames[0];
var pattern = this.fileName + ":" + this.lineNumber;
while(typeof(currentFrame) !== "undefined" &&
currentFrame !== null &&
currentFrame.indexOf(pattern) === -1) {
stackFrames.shift();
currentFrame = stackFrames[0];
}
var nextFrame = stackFrames[1];
// Special-case last stack frame, to stop shifting frames off the stack.
if (typeof(nextFrame) === "undefined" || nextFrame === null) {
return;
}
// Update fields to correspond with next stack frame
var nextFrameParts = nextFrame.match(/@(.*):(\d+)$/);
if (typeof(nextFrameParts) === "undefined" || nextFrameParts === null) {
return;
}
this.fileName = nextFrameParts[1];
// This should always succeed, since the regex matches "\d+"
this.lineNumber = parseInt(nextFrameParts[2]);
stackFrames.shift();
this.stack = stackFrames.join("\n");
}