sc-errors
Version:
Error types for use throughout SocketCluster
339 lines (293 loc) • 9.97 kB
JavaScript
const decycle = require('./decycle');
const isStrict = (function () { return !this; })();
function AuthTokenExpiredError(message, expiry) {
this.name = 'AuthTokenExpiredError';
this.message = message;
this.expiry = expiry;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
AuthTokenExpiredError.prototype = Object.create(Error.prototype);
function AuthTokenInvalidError(message) {
this.name = 'AuthTokenInvalidError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
AuthTokenInvalidError.prototype = Object.create(Error.prototype);
function AuthTokenNotBeforeError(message, date) {
this.name = 'AuthTokenNotBeforeError';
this.message = message;
this.date = date;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
AuthTokenNotBeforeError.prototype = Object.create(Error.prototype);
// For any other auth token error.
function AuthTokenError(message) {
this.name = 'AuthTokenError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
AuthTokenError.prototype = Object.create(Error.prototype);
// For any other auth error; not specifically related to the auth token itself.
function AuthError(message) {
this.name = 'AuthError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
AuthError.prototype = Object.create(Error.prototype);
function SilentMiddlewareBlockedError(message, type) {
this.name = 'SilentMiddlewareBlockedError';
this.message = message;
this.type = type;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
SilentMiddlewareBlockedError.prototype = Object.create(Error.prototype);
function InvalidActionError(message) {
this.name = 'InvalidActionError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
InvalidActionError.prototype = Object.create(Error.prototype);
function InvalidArgumentsError(message) {
this.name = 'InvalidArgumentsError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
InvalidArgumentsError.prototype = Object.create(Error.prototype);
function InvalidOptionsError(message) {
this.name = 'InvalidOptionsError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
InvalidOptionsError.prototype = Object.create(Error.prototype);
function InvalidMessageError(message) {
this.name = 'InvalidMessageError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
InvalidMessageError.prototype = Object.create(Error.prototype);
function SocketProtocolError(message, code) {
this.name = 'SocketProtocolError';
this.message = message;
this.code = code;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
SocketProtocolError.prototype = Object.create(Error.prototype);
function ServerProtocolError(message) {
this.name = 'ServerProtocolError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
ServerProtocolError.prototype = Object.create(Error.prototype);
function HTTPServerError(message) {
this.name = 'HTTPServerError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
HTTPServerError.prototype = Object.create(Error.prototype);
function ResourceLimitError(message) {
this.name = 'ResourceLimitError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
ResourceLimitError.prototype = Object.create(Error.prototype);
function TimeoutError(message) {
this.name = 'TimeoutError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
TimeoutError.prototype = Object.create(Error.prototype);
function BadConnectionError(message, type, code, reason) {
this.name = 'BadConnectionError';
this.message = message;
this.type = type;
this.code = code || 1001;
this.reason = reason || socketProtocolIgnoreStatuses[this.code] || '';
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
BadConnectionError.prototype = Object.create(Error.prototype);
function BrokerError(message) {
this.name = 'BrokerError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
BrokerError.prototype = Object.create(Error.prototype);
function ProcessExitError(message, code) {
this.name = 'ProcessExitError';
this.message = message;
this.code = code;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
ProcessExitError.prototype = Object.create(Error.prototype);
function UnknownError(message) {
this.name = 'UnknownError';
this.message = message;
if (Error.captureStackTrace && !isStrict) {
Error.captureStackTrace(this, arguments.callee);
} else {
this.stack = (new Error()).stack;
}
}
UnknownError.prototype = Object.create(Error.prototype);
// Expose all error types.
module.exports = {
AuthTokenExpiredError: AuthTokenExpiredError,
AuthTokenInvalidError: AuthTokenInvalidError,
AuthTokenNotBeforeError: AuthTokenNotBeforeError,
AuthTokenError: AuthTokenError,
AuthError: AuthError,
SilentMiddlewareBlockedError: SilentMiddlewareBlockedError,
InvalidActionError: InvalidActionError,
InvalidArgumentsError: InvalidArgumentsError,
InvalidOptionsError: InvalidOptionsError,
InvalidMessageError: InvalidMessageError,
SocketProtocolError: SocketProtocolError,
ServerProtocolError: ServerProtocolError,
HTTPServerError: HTTPServerError,
ResourceLimitError: ResourceLimitError,
TimeoutError: TimeoutError,
BadConnectionError: BadConnectionError,
BrokerError: BrokerError,
ProcessExitError: ProcessExitError,
UnknownError: UnknownError
};
const socketProtocolErrorStatuses = {
1001: 'Socket was disconnected',
1002: 'A WebSocket protocol error was encountered',
1003: 'Server terminated socket because it received invalid data',
1005: 'Socket closed without status code',
1006: 'Socket hung up',
1007: 'Message format was incorrect',
1008: 'Encountered a policy violation',
1009: 'Message was too big to process',
1010: 'Client ended the connection because the server did not comply with extension requirements',
1011: 'Server encountered an unexpected fatal condition',
4000: 'Server ping timed out',
4001: 'Client pong timed out',
4002: 'Server failed to sign auth token',
4003: 'Failed to complete handshake',
4004: 'Client failed to save auth token',
4005: 'Did not receive #handshake from client before timeout',
4006: 'Failed to bind socket to message broker',
4007: 'Client connection establishment timed out',
4008: 'Server rejected handshake from client',
4009: 'Server received a message before the client handshake'
};
const socketProtocolIgnoreStatuses = {
1000: 'Socket closed normally',
1001: socketProtocolErrorStatuses[1001]
};
module.exports.socketProtocolErrorStatuses = socketProtocolErrorStatuses;
module.exports.socketProtocolIgnoreStatuses = socketProtocolIgnoreStatuses;
// Convert an error into a JSON-compatible type which can later be hydrated
// back to its *original* form.
module.exports.dehydrateError = function dehydrateError(error) {
let dehydratedError;
if (error && typeof error === 'object') {
dehydratedError = {
message: error.message
};
for (let i of Object.keys(error)) {
dehydratedError[i] = error[i];
}
} else if (typeof error === 'function') {
dehydratedError = '[function ' + (typeof error.name === 'string' ? error.name : 'anonymous') + ']';
} else {
dehydratedError = error;
}
return decycle(dehydratedError);
};
// Convert a dehydrated error back to its *original* form.
module.exports.hydrateError = function hydrateError(error) {
let hydratedError = null;
if (error != null) {
if (typeof error === 'object') {
hydratedError = new Error(
typeof error.message === 'string' ? error.message : 'Invalid error message format'
);
if (typeof error.name === 'string') {
hydratedError.name = error.name;
}
for (let i of Object.keys(error)) {
if (hydratedError[i] === undefined) {
hydratedError[i] = error[i];
}
}
} else {
hydratedError = error;
}
}
return hydratedError;
};
module.exports.decycle = decycle;