mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-11 00:53:31 +01:00
Errors Standardization (#1246)
* errors and stuff * more errors * all the errors * fix build
This commit is contained in:
@@ -19,6 +19,7 @@ const Invite = require('../structures/Invite');
|
||||
const OAuth2Application = require('../structures/OAuth2Application');
|
||||
const ShardClientUtil = require('../sharding/ShardClientUtil');
|
||||
const VoiceBroadcast = require('./voice/VoiceBroadcast');
|
||||
const { Error, TypeError, RangeError } = require('../errors');
|
||||
|
||||
/**
|
||||
* The main hub for interacting with the Discord API, and the starting point for any bot.
|
||||
@@ -287,7 +288,7 @@ class Client extends EventEmitter {
|
||||
*/
|
||||
login(token) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof token !== 'string') throw new Error(Constants.Errors.INVALID_TOKEN);
|
||||
if (typeof token !== 'string') throw new Error('TOKEN_INVALID');
|
||||
token = token.replace(/^Bot\s*/i, '');
|
||||
this.manager.connectToWebSocket(token, resolve, reject);
|
||||
});
|
||||
@@ -375,7 +376,9 @@ class Client extends EventEmitter {
|
||||
* or -1 if the message cache lifetime is unlimited
|
||||
*/
|
||||
sweepMessages(lifetime = this.options.messageCacheLifetime) {
|
||||
if (typeof lifetime !== 'number' || isNaN(lifetime)) throw new TypeError('The lifetime must be a number.');
|
||||
if (typeof lifetime !== 'number' || isNaN(lifetime)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'Lifetime', 'a number');
|
||||
}
|
||||
if (lifetime <= 0) {
|
||||
this.emit('debug', 'Didn\'t sweep messages - lifetime is unlimited');
|
||||
return -1;
|
||||
@@ -524,41 +527,40 @@ class Client extends EventEmitter {
|
||||
*/
|
||||
_validateOptions(options = this.options) {
|
||||
if (typeof options.shardCount !== 'number' || isNaN(options.shardCount)) {
|
||||
throw new TypeError('The shardCount option must be a number.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'shardCount', 'a number');
|
||||
}
|
||||
if (typeof options.shardId !== 'number' || isNaN(options.shardId)) {
|
||||
throw new TypeError('The shardId option must be a number.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'shardId', 'a number');
|
||||
}
|
||||
if (options.shardCount < 0) throw new RangeError('The shardCount option must be at least 0.');
|
||||
if (options.shardId < 0) throw new RangeError('The shardId option must be at least 0.');
|
||||
if (options.shardCount < 0) throw new RangeError('CLIENT_INVALID_OPTION', 'shardCount', 'at least 0');
|
||||
if (options.shardId < 0) throw new RangeError('CLIENT_INVALID_OPTION', 'shardId', 'at least 0');
|
||||
if (options.shardId !== 0 && options.shardId >= options.shardCount) {
|
||||
throw new RangeError('The shardId option must be less than shardCount.');
|
||||
throw new RangeError('CLIENT_INVALID_OPTION', 'shardId', 'less than shardCount');
|
||||
}
|
||||
if (typeof options.messageCacheMaxSize !== 'number' || isNaN(options.messageCacheMaxSize)) {
|
||||
throw new TypeError('The messageCacheMaxSize option must be a number.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'messageCacheMaxSize', 'a number');
|
||||
}
|
||||
if (typeof options.messageCacheLifetime !== 'number' || isNaN(options.messageCacheLifetime)) {
|
||||
throw new TypeError('The messageCacheLifetime option must be a number.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'The messageCacheLifetime', 'a number');
|
||||
}
|
||||
if (typeof options.messageSweepInterval !== 'number' || isNaN(options.messageSweepInterval)) {
|
||||
throw new TypeError('The messageSweepInterval option must be a number.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'messageSweepInterval', 'a number');
|
||||
}
|
||||
if (typeof options.fetchAllMembers !== 'boolean') {
|
||||
throw new TypeError('The fetchAllMembers option must be a boolean.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'fetchAllMembers', 'a boolean');
|
||||
}
|
||||
if (typeof options.disableEveryone !== 'boolean') {
|
||||
throw new TypeError('The disableEveryone option must be a boolean.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'disableEveryone', 'a boolean');
|
||||
}
|
||||
if (typeof options.restWsBridgeTimeout !== 'number' || isNaN(options.restWsBridgeTimeout)) {
|
||||
throw new TypeError('The restWsBridgeTimeout option must be a number.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'restWsBridgeTimeout', 'a number');
|
||||
}
|
||||
if (typeof options.internalSharding !== 'boolean') {
|
||||
throw new TypeError('The internalSharding option must be a boolean.');
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'internalSharding', 'a boolean');
|
||||
}
|
||||
if (options.internalSharding && ('shardCount' in options || 'shardId' in options)) {
|
||||
throw new TypeError('You cannot specify shardCount/shardId if you are using internal sharding.');
|
||||
if (!(options.disabledEvents instanceof Array)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'disabledEvents', 'an Array');
|
||||
}
|
||||
if (!(options.disabledEvents instanceof Array)) throw new TypeError('The disabledEvents option must be an Array.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ const Channel = require('../structures/Channel');
|
||||
const GuildMember = require('../structures/GuildMember');
|
||||
const Emoji = require('../structures/Emoji');
|
||||
const ReactionEmoji = require('../structures/ReactionEmoji');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
|
||||
/**
|
||||
* The DataResolver identifies different objects and tries to resolve a specific piece of information from them, e.g.
|
||||
@@ -194,14 +195,14 @@ class ClientDataResolver {
|
||||
snekfetch.get(resource)
|
||||
.end((err, res) => {
|
||||
if (err) return reject(err);
|
||||
if (!(res.body instanceof Buffer)) return reject(new TypeError('The response body isn\'t a Buffer.'));
|
||||
if (!(res.body instanceof Buffer)) return reject(new TypeError('REQ_BODY_TYPE'));
|
||||
return resolve(res.body);
|
||||
});
|
||||
} else {
|
||||
const file = path.resolve(resource);
|
||||
fs.stat(file, (err, stats) => {
|
||||
if (err) return reject(err);
|
||||
if (!stats || !stats.isFile()) return reject(new Error(`The file could not be found: ${file}`));
|
||||
if (!stats || !stats.isFile()) return reject(new Error('FILE_NOT_FOUND', file));
|
||||
fs.readFile(file, (err2, data) => {
|
||||
if (err2) reject(err2); else resolve(data);
|
||||
});
|
||||
@@ -211,7 +212,7 @@ class ClientDataResolver {
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(new TypeError('The resource must be a string or Buffer.'));
|
||||
return Promise.reject(new TypeError('REQ_RESOURCE_TYPE'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const Constants = require('../util/Constants');
|
||||
const WebSocketConnection = require('./websocket/WebSocketConnection');
|
||||
const { Error } = require('../errors');
|
||||
|
||||
/**
|
||||
* Manages the state and background tasks of the client.
|
||||
@@ -37,16 +38,16 @@ class ClientManager {
|
||||
connectToWebSocket(token, resolve, reject) {
|
||||
this.client.emit(Constants.Events.DEBUG, `Authenticated using token ${token}`);
|
||||
this.client.token = token;
|
||||
const timeout = this.client.setTimeout(() => reject(new Error(Constants.Errors.TOOK_TOO_LONG)), 1000 * 300);
|
||||
const timeout = this.client.setTimeout(() => reject(new Error('INVALID_TOKEN')), 1000 * 300);
|
||||
this.client.api.gateway.get().then(res => {
|
||||
const protocolVersion = Constants.DefaultOptions.ws.version;
|
||||
const gateway = `${res.url}/?v=${protocolVersion}&encoding=${WebSocketConnection.ENCODING}`;
|
||||
this.client.emit(Constants.Events.DEBUG, `Using gateway ${gateway}`);
|
||||
this.client.ws.connect(gateway);
|
||||
this.client.ws.connection.once('close', event => {
|
||||
if (event.code === 4004) reject(new Error(Constants.Errors.BAD_LOGIN));
|
||||
if (event.code === 4010) reject(new Error(Constants.Errors.INVALID_SHARD));
|
||||
if (event.code === 4011) reject(new Error(Constants.Errors.SHARDING_REQUIRED));
|
||||
if (event.code === 4004) reject(new Error('TOKEN_INVALID'));
|
||||
if (event.code === 4010) reject(new Error('SHARDING_INVALID'));
|
||||
if (event.code === 4011) reject(new Error('SHARDING_REQUIRED'));
|
||||
});
|
||||
this.client.once(Constants.Events.READY, () => {
|
||||
resolve(token);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const querystring = require('querystring');
|
||||
const snekfetch = require('snekfetch');
|
||||
const Constants = require('../../util/Constants');
|
||||
const { Error } = require('../../errors');
|
||||
|
||||
class APIRequest {
|
||||
constructor(rest, method, path, options) {
|
||||
@@ -28,7 +28,7 @@ class APIRequest {
|
||||
} else if (this.client.token) {
|
||||
return this.client.token;
|
||||
}
|
||||
throw new Error(Constants.Errors.NO_TOKEN);
|
||||
throw new Error('TOKEN_MISSING');
|
||||
}
|
||||
|
||||
gen() {
|
||||
|
||||
@@ -3,7 +3,7 @@ const SequentialRequestHandler = require('./RequestHandlers/Sequential');
|
||||
const BurstRequestHandler = require('./RequestHandlers/Burst');
|
||||
const APIRequest = require('./APIRequest');
|
||||
const mountApi = require('./APIRouter');
|
||||
const Constants = require('../../util/Constants');
|
||||
const { Error } = require('../../errors');
|
||||
|
||||
class RESTManager {
|
||||
constructor(client) {
|
||||
@@ -39,7 +39,7 @@ class RESTManager {
|
||||
case 'burst':
|
||||
return BurstRequestHandler;
|
||||
default:
|
||||
throw new Error(Constants.Errors.INVALID_RATE_LIMIT_METHOD);
|
||||
throw new Error('RATELIMIT_INVALID_METHOD');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const Collection = require('../../util/Collection');
|
||||
const VoiceConnection = require('./VoiceConnection');
|
||||
const { Error } = require('../../errors');
|
||||
|
||||
/**
|
||||
* Manages all the voice stuff for the client.
|
||||
@@ -44,11 +45,7 @@ class ClientVoiceManager {
|
||||
joinChannel(channel) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!channel.joinable) {
|
||||
if (channel.full) {
|
||||
throw new Error('You do not have permission to join this voice channel; it is full.');
|
||||
} else {
|
||||
throw new Error('You do not have permission to join this voice channel.');
|
||||
}
|
||||
throw new Error('VOICE_JOIN_CHANNEL', channel.full);
|
||||
}
|
||||
|
||||
let connection = this.connections.get(channel.guild.id);
|
||||
|
||||
@@ -6,6 +6,7 @@ const AudioPlayer = require('./player/AudioPlayer');
|
||||
const VoiceReceiver = require('./receiver/VoiceReceiver');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const Prism = require('prism-media');
|
||||
const { Error } = require('../../errors');
|
||||
|
||||
/**
|
||||
* Represents a connection to a guild's voice server.
|
||||
@@ -341,8 +342,8 @@ class VoiceConnection extends EventEmitter {
|
||||
*/
|
||||
connect() {
|
||||
if (this.status !== Constants.VoiceStatus.RECONNECTING) {
|
||||
if (this.sockets.ws) throw new Error('There is already an existing WebSocket connection.');
|
||||
if (this.sockets.udp) throw new Error('There is already an existing UDP connection.');
|
||||
if (this.sockets.ws) throw new Error('WS_CONNECTION_EXISTS');
|
||||
if (this.sockets.udp) throw new Error('UDP_CONNECTION_EXISTS');
|
||||
}
|
||||
|
||||
if (this.sockets.ws) this.sockets.ws.shutdown();
|
||||
|
||||
@@ -2,6 +2,7 @@ const udp = require('dgram');
|
||||
const dns = require('dns');
|
||||
const Constants = require('../../util/Constants');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const { Error } = require('../../errors');
|
||||
|
||||
/**
|
||||
* Represents a UDP client for a Voice Connection.
|
||||
@@ -89,8 +90,8 @@ class VoiceConnectionUDPClient extends EventEmitter {
|
||||
*/
|
||||
send(packet) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.socket) throw new Error('Tried to send a UDP packet, but there is no socket available.');
|
||||
if (!this.discordAddress || !this.discordPort) throw new Error('Malformed UDP address or port.');
|
||||
if (!this.socket) throw new Error('UDP_SEND_FAIL');
|
||||
if (!this.discordAddress || !this.discordPort) throw new Error('UDP_ADDRESS_MALFORMED');
|
||||
this.socket.send(packet, 0, packet.length, this.discordPort, this.discordAddress, error => {
|
||||
if (error) reject(error); else resolve(packet);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const Constants = require('../../util/Constants');
|
||||
const SecretKey = require('./util/SecretKey');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const { Error } = require('../../errors');
|
||||
|
||||
let WebSocket;
|
||||
try {
|
||||
@@ -88,9 +89,7 @@ class VoiceWebSocket extends EventEmitter {
|
||||
*/
|
||||
send(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
||||
throw new Error(`Voice websocket not open to send ${data}.`);
|
||||
}
|
||||
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) throw new Error('WS_NOT_OPEN', data);
|
||||
this.ws.send(data, null, error => {
|
||||
if (error) reject(error); else resolve(data);
|
||||
});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
const { Error } = require('../../../errors');
|
||||
|
||||
const list = [
|
||||
require('./NodeOpusEngine'),
|
||||
require('./OpusScriptEngine'),
|
||||
@@ -30,5 +32,5 @@ exports.fetch = engineOptions => {
|
||||
|
||||
exports.guaranteeOpusEngine = () => {
|
||||
if (typeof opusEngineFound === 'undefined') opusEngineFound = Boolean(exports.fetch());
|
||||
if (!opusEngineFound) throw new Error('Couldn\'t find an Opus engine.');
|
||||
if (!opusEngineFound) throw new Error('OPUS_ENGINE_MISSING');
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ const EventEmitter = require('events').EventEmitter;
|
||||
const secretbox = require('../util/Secretbox');
|
||||
const Readable = require('./VoiceReadable');
|
||||
const OpusEncoders = require('../opus/OpusEngineList');
|
||||
const { Error } = require('../../../errors');
|
||||
|
||||
const nonce = Buffer.alloc(24);
|
||||
nonce.fill(0);
|
||||
@@ -122,8 +123,8 @@ class VoiceReceiver extends EventEmitter {
|
||||
*/
|
||||
createOpusStream(user) {
|
||||
user = this.voiceConnection.voiceManager.client.resolver.resolveUser(user);
|
||||
if (!user) throw new Error('Couldn\'t resolve the user to create Opus stream.');
|
||||
if (this.opusStreams.get(user.id)) throw new Error('There is already an existing stream for that user.');
|
||||
if (!user) throw new Error('VOICE_USER_MISSING');
|
||||
if (this.opusStreams.get(user.id)) throw new Error('VOICE_STREAM_EXISTS');
|
||||
const stream = new Readable();
|
||||
this.opusStreams.set(user.id, stream);
|
||||
return stream;
|
||||
@@ -137,8 +138,8 @@ class VoiceReceiver extends EventEmitter {
|
||||
*/
|
||||
createPCMStream(user) {
|
||||
user = this.voiceConnection.voiceManager.client.resolver.resolveUser(user);
|
||||
if (!user) throw new Error('Couldn\'t resolve the user to create PCM stream.');
|
||||
if (this.pcmStreams.get(user.id)) throw new Error('There is already an existing stream for that user.');
|
||||
if (!user) throw new Error('VOICE_USER_MISSING');
|
||||
if (this.pcmStreams.get(user.id)) throw new Error('VOICE_STREAM_EXISTS');
|
||||
const stream = new Readable();
|
||||
this.pcmStreams.set(user.id, stream);
|
||||
return stream;
|
||||
|
||||
Reference in New Issue
Block a user