Skip to content

Commit

Permalink
refactor: make errors take objects instead of many params (#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranet authored Jan 29, 2021
1 parent 6293ad0 commit c30ad4c
Show file tree
Hide file tree
Showing 31 changed files with 372 additions and 170 deletions.
8 changes: 4 additions & 4 deletions src/arguments/CoreBoolean.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PieceContext } from '@sapphire/pieces';
import { Argument, ArgumentResult } from '../lib/structures/Argument';
import { Argument, ArgumentContext, ArgumentResult } from '../lib/structures/Argument';

const truths = ['1', 'true', '+', 't', 'yes', 'y'];
const falses = ['0', 'false', '-', 'f', 'no', 'n'];
Expand All @@ -9,11 +9,11 @@ export class CoreArgument extends Argument<boolean> {
super(context, { name: 'boolean' });
}

public run(argument: string): ArgumentResult<boolean> {
const boolean = argument.toLowerCase();
public run(parameter: string, context: ArgumentContext): ArgumentResult<boolean> {
const boolean = parameter.toLowerCase();
if (truths.includes(boolean)) return this.ok(true);
if (falses.includes(boolean)) return this.ok(false);

return this.error(argument, 'ArgumentBooleanInvalidBoolean', 'The argument did not resolve to a boolean.');
return this.error({ parameter, identifier: 'ArgumentBooleanInvalidBoolean', message: 'The argument did not resolve to a boolean.', context });
}
}
9 changes: 7 additions & 2 deletions src/arguments/CoreCategoryChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ export class CoreArgument extends ExtendedArgument<'guildChannel', CategoryChann
});
}

public handle(channel: GuildChannel, { argument }: ExtendedArgumentContext): ArgumentResult<CategoryChannel> {
public handle(channel: GuildChannel, context: ExtendedArgumentContext): ArgumentResult<CategoryChannel> {
return isCategoryChannel(channel)
? this.ok(channel)
: this.error(argument, 'ArgumentCategoryChannelInvalidChannel', 'The argument did not resolve to a category channel.');
: this.error({
parameter: context.parameter,
identifier: 'ArgumentCategoryChannelInvalidChannel',
message: 'The argument did not resolve to a category channel.',
context
});
}
}
11 changes: 8 additions & 3 deletions src/arguments/CoreChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ export class CoreArgument extends Argument<Channel> {
super(context, { name: 'channel' });
}

public run(argument: string, context: ArgumentContext): ArgumentResult<Channel> {
const channel = (context.message.guild ? context.message.guild.channels : this.context.client.channels).cache.get(argument);
public run(parameter: string, context: ArgumentContext): ArgumentResult<Channel> {
const channel = (context.message.guild ? context.message.guild.channels : this.context.client.channels).cache.get(parameter);

if (!channel) {
return this.error(argument, 'ArgumentChannelMissingChannel', 'The argument did not resolve to a channel.');
return this.error({
parameter,
identifier: 'ArgumentChannelMissingChannel',
message: 'The argument did not resolve to a channel.',
context
});
}

return this.ok(channel);
Expand Down
24 changes: 12 additions & 12 deletions src/arguments/CoreDMChannel.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { isDMChannel } from '@sapphire/discord.js-utilities';
import type { PieceContext } from '@sapphire/pieces';
import type { DMChannel } from 'discord.js';
import { Argument, ArgumentResult } from '../lib/structures/Argument';
import type { Channel, DMChannel } from 'discord.js';
import type { ArgumentResult } from '../lib/structures/Argument';
import { ExtendedArgument, ExtendedArgumentContext } from '../lib/structures/ExtendedArgument';

export class CoreArgument extends Argument<DMChannel> {
export class CoreArgument extends ExtendedArgument<'channel', DMChannel> {
public constructor(context: PieceContext) {
super(context, { name: 'dmChannel' });
super(context, { baseArgument: 'channel', name: 'dmChannel' });
}

public run(argument: string): ArgumentResult<DMChannel> {
const channel = this.context.client.channels.cache.get(argument);

if (!channel) {
return this.error(argument, 'ArgumentChannelMissingChannel', 'The argument did not resolve to a channel.');
}

public handle(channel: Channel, context: ExtendedArgumentContext): ArgumentResult<DMChannel> {
return isDMChannel(channel)
? this.ok(channel)
: this.error(argument, 'ArgumentDMChannelInvalidChannel', 'The argument did not resolve to a DM channel.');
: this.error({
parameter: context.parameter,
identifier: 'ArgumentDMChannelInvalidChannel',
message: 'The argument did not resolve to a DM channel.',
context
});
}
}
17 changes: 12 additions & 5 deletions src/arguments/CoreDate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,25 @@ export class CoreArgument extends Argument<Date> {
super(context, { name: 'date' });
}

public run(argument: string, context: ArgumentContext): ArgumentResult<Date> {
const parsed = new Date(argument);
public run(parameter: string, context: ArgumentContext): ArgumentResult<Date> {
const parsed = new Date(parameter);
const time = parsed.getTime();

if (Number.isNaN(time)) {
return this.error(argument, 'ArgumentDateInvalidNumber', 'The argument did not resolve to a valid date.');
return this.error({
parameter,
identifier: 'ArgumentDateInvalidNumber',
message: 'The argument did not resolve to a valid date.',
context
});
}

if (typeof context.minimum === 'number' && time < context.minimum) {
return this.error(argument, 'ArgumentDateTooSmall', 'The argument is too small.');
return this.error({ parameter, identifier: 'ArgumentDateTooSmall', message: 'The argument is too small.', context });
}

if (typeof context.maximum === 'number' && time > context.maximum) {
return this.error(argument, 'ArgumentDateTooBig', 'The argument is too big.');
return this.error({ parameter, identifier: 'ArgumentDateTooBig', message: 'The argument is too big.', context });
}

return this.ok(parsed);
Expand Down
27 changes: 22 additions & 5 deletions src/arguments/CoreFloat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,34 @@ export class CoreArgument extends Argument<number> {
super(context, { name: 'float' });
}

public run(argument: string, context: ArgumentContext): ArgumentResult<number> {
const parsed = Number(argument);
public run(parameter: string, context: ArgumentContext): ArgumentResult<number> {
const parsed = Number(parameter);

if (Number.isNaN(parsed)) {
return this.error(argument, 'ArgumentFloatInvalidFloat', 'The argument did not resolve to a valid floating point number.');
return this.error({
parameter,
identifier: 'ArgumentFloatInvalidFloat',
message: 'The argument did not resolve to a valid floating point number.',
context
});
}

if (typeof context.minimum === 'number' && parsed < context.minimum) {
return this.error(argument, 'ArgumentFloatTooSmall', `The argument must be greater than ${context.minimum}.`);
return this.error({
parameter,
identifier: 'ArgumentFloatTooSmall',
message: `The argument must be greater than ${context.minimum}.`,
context
});
}

if (typeof context.maximum === 'number' && parsed > context.maximum) {
return this.error(argument, 'ArgumentFloatTooBig', `The argument must be less than ${context.maximum}.`);
return this.error({
parameter,
identifier: 'ArgumentFloatTooBig',
message: `The argument must be less than ${context.maximum}.`,
context
});
}

return this.ok(parsed);
Expand Down
18 changes: 14 additions & 4 deletions src/arguments/CoreGuildChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,26 @@ export class CoreArgument extends Argument<GuildChannel> {
super(context, { name: 'guildChannel' });
}

public run(argument: string, context: ArgumentContext): ArgumentResult<GuildChannel> {
public run(parameter: string, context: ArgumentContext): ArgumentResult<GuildChannel> {
const { guild } = context.message;
if (!guild) {
return this.error(argument, 'ArgumentGuildChannelMissingGuild', 'The argument must be run in a guild.');
return this.error({
parameter,
identifier: 'ArgumentGuildChannelMissingGuild',
message: 'The argument must be run in a guild.',
context
});
}

const channel = this.resolveByID(argument, guild) ?? this.resolveByQuery(argument, guild);
const channel = this.resolveByID(parameter, guild) ?? this.resolveByQuery(parameter, guild);
return channel
? this.ok(channel)
: this.error(argument, 'ArgumentGuildChannelUnknownChannel', 'The argument did not resolve to a guild channel.');
: this.error({
parameter,
identifier: 'ArgumentGuildChannelUnknownChannel',
message: 'The argument did not resolve to a guild channel.',
context
});
}

private resolveByID(argument: string, guild: Guild): GuildChannel | null {
Expand Down
13 changes: 9 additions & 4 deletions src/arguments/CoreHyperlink.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import type { PieceContext } from '@sapphire/pieces';
import { URL } from 'url';
import { Argument, ArgumentResult } from '../lib/structures/Argument';
import { Argument, ArgumentContext, ArgumentResult } from '../lib/structures/Argument';

export class CoreArgument extends Argument<URL> {
public constructor(context: PieceContext) {
super(context, { name: 'hyperlink', aliases: ['url'] });
}

public run(argument: string): ArgumentResult<URL> {
public run(parameter: string, context: ArgumentContext): ArgumentResult<URL> {
try {
return this.ok(new URL(argument));
return this.ok(new URL(parameter));
} catch {
return this.error(argument, 'ArgumentHyperlinkInvalidURL', 'The argument did not resolve to a valid URL.');
return this.error({
parameter,
identifier: 'ArgumentHyperlinkInvalidURL',
message: 'The argument did not resolve to a valid URL.',
context
});
}
}
}
27 changes: 22 additions & 5 deletions src/arguments/CoreInteger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,34 @@ export class CoreArgument extends Argument<number> {
super(context, { name: 'integer' });
}

public run(argument: string, context: ArgumentContext): ArgumentResult<number> {
const parsed = Number(argument);
public run(parameter: string, context: ArgumentContext): ArgumentResult<number> {
const parsed = Number(parameter);

if (!Number.isInteger(parsed)) {
return this.error(argument, 'ArgumentIntegerInvalidNumber', 'The argument did not resolve to an integer.');
return this.error({
parameter,
identifier: 'ArgumentIntegerInvalidNumber',
message: 'The argument did not resolve to an integer.',
context
});
}

if (typeof context.minimum === 'number' && parsed < context.minimum) {
return this.error(argument, 'ArgumentIntegerTooSmall', `The argument must be greater than ${context.minimum}.`);
return this.error({
parameter,
identifier: 'ArgumentIntegerTooSmall',
message: `The argument must be greater than ${context.minimum}.`,
context
});
}

if (typeof context.maximum === 'number' && parsed > context.maximum) {
return this.error(argument, 'ArgumentIntegerTooBig', `The argument must be less than ${context.maximum}.`);
return this.error({
parameter,
identifier: 'ArgumentIntegerTooBig',
message: `The argument must be less than ${context.maximum}.`,
context
});
}

return this.ok(parsed);
Expand Down
12 changes: 7 additions & 5 deletions src/arguments/CoreMember.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { SnowflakeRegex, UserOrMemberMentionRegex } from '@sapphire/discord-utilities';
import type { PieceContext } from '@sapphire/pieces';
import type { GuildMember, Guild } from 'discord.js';
import type { Guild, GuildMember } from 'discord.js';
import { Argument, ArgumentContext, AsyncArgumentResult } from '../lib/structures/Argument';

export class CoreArgument extends Argument<GuildMember> {
public constructor(context: PieceContext) {
super(context, { name: 'member' });
}

public async run(argument: string, context: ArgumentContext): AsyncArgumentResult<GuildMember> {
public async run(parameter: string, context: ArgumentContext): AsyncArgumentResult<GuildMember> {
const { guild } = context.message;
if (!guild) {
return this.error(argument, 'ArgumentMemberMissingGuild', 'The argument must be run on a guild.');
return this.error({ parameter, identifier: 'ArgumentMemberMissingGuild', message: 'The argument must be run on a guild.', context });
}

const member = (await this.resolveByID(argument, guild)) ?? (await this.resolveByQuery(argument, guild));
return member ? this.ok(member) : this.error(argument, 'ArgumentMemberUnknownMember', 'The argument did not resolve to a member.');
const member = (await this.resolveByID(parameter, guild)) ?? (await this.resolveByQuery(parameter, guild));
return member
? this.ok(member)
: this.error({ parameter, identifier: 'ArgumentMemberUnknownMember', message: 'The argument did not resolve to a member.', context });
}

private async resolveByID(argument: string, guild: Guild): Promise<GuildMember | null> {
Expand Down
8 changes: 5 additions & 3 deletions src/arguments/CoreMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ export class CoreArgument extends Argument<Message> {
super(context, { name: 'message' });
}

public async run(argument: string, context: MessageArgumentContext): AsyncArgumentResult<Message> {
const message = (await this.resolveByID(argument, context)) ?? (await this.resolveByLink(argument, context));
return message ? this.ok(message) : this.error(argument, 'ArgumentMessageUnknownMessage', 'The argument did not resolve to a message.');
public async run(parameter: string, context: MessageArgumentContext): AsyncArgumentResult<Message> {
const message = (await this.resolveByID(parameter, context)) ?? (await this.resolveByLink(parameter, context));
return message
? this.ok(message)
: this.error({ parameter, identifier: 'ArgumentMessageUnknownMessage', message: 'The argument did not resolve to a message.', context });
}

private async resolveByID(argument: string, context: MessageArgumentContext): Promise<Message | null> {
Expand Down
9 changes: 7 additions & 2 deletions src/arguments/CoreNewsChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ export class CoreArgument extends ExtendedArgument<'guildChannel', NewsChannel>
});
}

public handle(channel: GuildChannel, { argument }: ExtendedArgumentContext): ArgumentResult<NewsChannel> {
public handle(channel: GuildChannel, context: ExtendedArgumentContext): ArgumentResult<NewsChannel> {
return isNewsChannel(channel)
? this.ok(channel)
: this.error(argument, 'ArgumentNewsChannelInvalidChannel', 'The argument did not resolve to a news channel.');
: this.error({
parameter: context.parameter,
identifier: 'ArgumentNewsChannelInvalidChannel',
message: 'The argument did not resolve to a news channel.',
context
});
}
}
27 changes: 22 additions & 5 deletions src/arguments/CoreNumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,34 @@ export class CoreArgument extends Argument<number> {
super(context, { name: 'number' });
}

public run(argument: string, context: ArgumentContext): ArgumentResult<number> {
const parsed = Number(argument);
public run(parameter: string, context: ArgumentContext): ArgumentResult<number> {
const parsed = Number(parameter);

if (Number.isNaN(parsed)) {
return this.error(argument, 'ArgumentNumberInvalidNumber', 'The argument did not resolve to a valid number.');
return this.error({
parameter,
identifier: 'ArgumentNumberInvalidNumber',
message: 'The argument did not resolve to a valid number.',
context
});
}

if (typeof context.minimum === 'number' && parsed < context.minimum) {
return this.error(argument, 'ArgumentNumberTooSmall', 'The argument is too small.');
return this.error({
parameter,
identifier: 'ArgumentNumberTooSmall',
message: `The argument must be greater than ${context.minimum}.`,
context
});
}

if (typeof context.maximum === 'number' && parsed > context.maximum) {
return this.error(argument, 'ArgumentNumberTooBig', 'The argument is too big.');
return this.error({
parameter,
identifier: 'ArgumentNumberTooBig',
message: `The argument must be smaller than ${context.maximum}.`,
context
});
}

return this.ok(parsed);
Expand Down
10 changes: 6 additions & 4 deletions src/arguments/CoreRole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ export class CoreArgument extends Argument<Role> {
super(context, { name: 'role' });
}

public async run(argument: string, context: ArgumentContext): AsyncArgumentResult<Role> {
public async run(parameter: string, context: ArgumentContext): AsyncArgumentResult<Role> {
const { guild } = context.message;
if (!guild) {
return this.error(argument, 'ArgumentRoleMissingGuild', 'The argument must be run on a guild.');
return this.error({ parameter, identifier: 'ArgumentRoleMissingGuild', message: 'The argument must be run on a guild.', context });
}

const role = (await this.resolveByID(argument, guild)) ?? this.resolveByQuery(argument, guild);
return role ? this.ok(role) : this.error(argument, 'ArgumentRoleUnknownRole', 'The argument did not resolve to a role.');
const role = (await this.resolveByID(parameter, guild)) ?? this.resolveByQuery(parameter, guild);
return role
? this.ok(role)
: this.error({ parameter, identifier: 'ArgumentRoleUnknownRole', message: 'The argument did not resolve to a role.', context });
}

private async resolveByID(argument: string, guild: Guild): Promise<Role | null> {
Expand Down
Loading

0 comments on commit c30ad4c

Please sign in to comment.