Simplify work with errors
This commit is contained in:
parent
fec538be86
commit
4ff55b5850
@ -31,12 +31,12 @@ export class ActionController {
|
||||
ensureSameVillage(args: Args, task: Task) {
|
||||
let villageId = args.villageId;
|
||||
if (villageId === undefined) {
|
||||
throw new ActionError(task.id, 'Undefined village id');
|
||||
throw new ActionError('Undefined village id');
|
||||
}
|
||||
|
||||
const activeVillageId = grabActiveVillageId();
|
||||
if (villageId !== activeVillageId) {
|
||||
throw new TryLaterError(task.id, aroundMinutes(1), 'Not same village');
|
||||
throw new TryLaterError(aroundMinutes(1), 'Not same village');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,14 +12,14 @@ export class BuildBuildingAction extends ActionController {
|
||||
|
||||
const buildTypeId = args.buildTypeId;
|
||||
if (buildTypeId === undefined) {
|
||||
throw new ActionError(task.id, 'Undefined build type id');
|
||||
throw new ActionError('Undefined build type id');
|
||||
}
|
||||
|
||||
try {
|
||||
clickBuildButton(buildTypeId);
|
||||
} catch (e) {
|
||||
if (e instanceof GrabError) {
|
||||
throw new TryLaterError(task.id, aroundMinutes(5), 'No upgrade button, try later');
|
||||
throw new TryLaterError(aroundMinutes(5), 'No upgrade button, try later');
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ export class CheckBuildingRemainingTimeAction extends ActionController {
|
||||
async run(args: Args, task: Task): Promise<any> {
|
||||
const info = this.grabBuildingQueueInfoOrDefault();
|
||||
if (info.seconds > 0) {
|
||||
throw new TryLaterError(task.id, info.seconds + 1, 'Building queue is full');
|
||||
throw new TryLaterError(info.seconds + 1, 'Building queue is full');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ export class SendOnAdventureAction extends ActionController {
|
||||
this.checkConfig(easiest, Number(hero.health));
|
||||
}
|
||||
|
||||
throw new AbortTaskError(task.id, 'No suitable adventure');
|
||||
throw new AbortTaskError('No suitable adventure');
|
||||
}
|
||||
|
||||
private checkConfig(adventure: Adventure, health: number) {
|
||||
|
@ -7,50 +7,50 @@ import { getNumber, toNumber } from '../utils';
|
||||
@registerAction
|
||||
export class TrainTrooperAction extends ActionController {
|
||||
async run(args: Args, task: Task): Promise<any> {
|
||||
const troopId = this.getTroopId(args, task);
|
||||
const trainCount = this.getTrainCount(args, task);
|
||||
const troopId = this.getTroopId(args);
|
||||
const trainCount = this.getTrainCount(args);
|
||||
|
||||
const block = jQuery(`#nonFavouriteTroops .innerTroopWrapper.troop${troopId}`);
|
||||
if (block.length !== 1) {
|
||||
throw new ActionError(task.id, `Troop block not found`);
|
||||
throw new ActionError(`Troop block not found`);
|
||||
}
|
||||
|
||||
const countLink = block.find('.cta a');
|
||||
if (countLink.length !== 1) {
|
||||
throw new ActionError(task.id, `Link with max count not found`);
|
||||
throw new ActionError(`Link with max count not found`);
|
||||
}
|
||||
|
||||
const maxCount = getNumber(countLink.text());
|
||||
if (maxCount < trainCount) {
|
||||
throw new TryLaterError(task.id, 20 * 60, `Max count ${maxCount} less then need ${trainCount}`);
|
||||
throw new TryLaterError(20 * 60, `Max count ${maxCount} less then need ${trainCount}`);
|
||||
}
|
||||
|
||||
const input = block.find(`input[name="t${troopId}"]`);
|
||||
if (input.length !== 1) {
|
||||
throw new ActionError(task.id, `Input element not found`);
|
||||
throw new ActionError(`Input element not found`);
|
||||
}
|
||||
|
||||
const trainButton = jQuery('.startTraining.green').first();
|
||||
if (trainButton.length !== 1) {
|
||||
throw new ActionError(task.id, 'Train button not found');
|
||||
throw new ActionError('Train button not found');
|
||||
}
|
||||
|
||||
input.val(trainCount);
|
||||
trainButton.trigger('click');
|
||||
}
|
||||
|
||||
private getTroopId(args: Args, task: Task): number {
|
||||
private getTroopId(args: Args): number {
|
||||
const troopId = toNumber(args.troopId);
|
||||
if (troopId === undefined) {
|
||||
throw new ActionError(task.id, `Troop id must be a number, given "${args.troopId}"`);
|
||||
throw new ActionError(`Troop id must be a number, given "${args.troopId}"`);
|
||||
}
|
||||
return troopId;
|
||||
}
|
||||
|
||||
private getTrainCount(args: Args, task: Task): number {
|
||||
private getTrainCount(args: Args): number {
|
||||
const trainCount = toNumber(args.trainCount);
|
||||
if (trainCount === undefined) {
|
||||
throw new ActionError(task.id, `Train count must be a number, given "${args.trainCount}"`);
|
||||
throw new ActionError(`Train count must be a number, given "${args.trainCount}"`);
|
||||
}
|
||||
return trainCount;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export class UpgradeBuildingAction extends ActionController {
|
||||
clickUpgradeButton();
|
||||
} catch (e) {
|
||||
if (e instanceof GrabError) {
|
||||
throw new TryLaterError(task.id, aroundMinutes(5), 'No upgrade button, try later');
|
||||
throw new TryLaterError(aroundMinutes(5), 'No upgrade button, try later');
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { ActionController, registerAction } from './ActionController';
|
||||
import { Args } from '../Command';
|
||||
import { ActionError, GrabError, TryLaterError } from '../Errors';
|
||||
import { ActionError, TryLaterError } from '../Errors';
|
||||
import { Task } from '../Queue/TaskQueue';
|
||||
import { clickUpgradeButton } from '../Page/BuildingPage';
|
||||
import { grabResourceDeposits } from '../Page/SlotBlock';
|
||||
import { UpgradeBuildingTask } from '../Task/UpgradeBuildingTask';
|
||||
import { ResourceDeposit } from '../Game';
|
||||
@ -13,7 +12,7 @@ export class UpgradeResourceToLevel extends ActionController {
|
||||
async run(args: Args, task: Task): Promise<any> {
|
||||
const deposits = grabResourceDeposits();
|
||||
if (deposits.length === 0) {
|
||||
throw new ActionError(task.id, 'No deposits');
|
||||
throw new ActionError('No deposits');
|
||||
}
|
||||
|
||||
const villageId = args.villageId;
|
||||
@ -39,13 +38,13 @@ export class UpgradeResourceToLevel extends ActionController {
|
||||
const notUpgraded = deposits.sort((x, y) => x.level - y.level).filter(isDepositTaskNotInQueue);
|
||||
|
||||
if (notUpgraded.length === 0) {
|
||||
throw new TryLaterError(task.id, aroundMinutes(10), 'No available deposits');
|
||||
throw new TryLaterError(aroundMinutes(10), 'No available deposits');
|
||||
}
|
||||
|
||||
for (let dep of notUpgraded) {
|
||||
this.scheduler.scheduleTask(UpgradeBuildingTask.name, { villageId, buildId: dep.buildId });
|
||||
}
|
||||
|
||||
throw new TryLaterError(task.id, aroundMinutes(10), 'Sleep for next round');
|
||||
throw new TryLaterError(aroundMinutes(10), 'Sleep for next round');
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
import { TaskId } from './Queue/TaskQueue';
|
||||
|
||||
export class GrabError extends Error {
|
||||
constructor(msg: string = '') {
|
||||
super(msg);
|
||||
@ -8,30 +6,24 @@ export class GrabError extends Error {
|
||||
}
|
||||
|
||||
export class ActionError extends Error {
|
||||
readonly taskId: TaskId;
|
||||
constructor(taskId: TaskId, msg: string = '') {
|
||||
constructor(msg: string = '') {
|
||||
super(msg);
|
||||
this.taskId = taskId;
|
||||
Object.setPrototypeOf(this, ActionError.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class AbortTaskError extends Error {
|
||||
readonly taskId: TaskId;
|
||||
constructor(taskId: TaskId, msg: string = '') {
|
||||
constructor(msg: string = '') {
|
||||
super(msg);
|
||||
this.taskId = taskId;
|
||||
Object.setPrototypeOf(this, AbortTaskError.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class TryLaterError extends Error {
|
||||
readonly seconds: number;
|
||||
readonly taskId: TaskId;
|
||||
|
||||
constructor(taskId: TaskId, seconds: number, msg: string = '') {
|
||||
constructor(seconds: number, msg: string = '') {
|
||||
super(msg);
|
||||
this.taskId = taskId;
|
||||
this.seconds = seconds;
|
||||
Object.setPrototypeOf(this, TryLaterError.prototype);
|
||||
}
|
||||
|
@ -43,10 +43,10 @@ export class Executor {
|
||||
await sleepMicro();
|
||||
|
||||
const currentTs = timestamp();
|
||||
const taskCommand = this.scheduler.nextTask(currentTs);
|
||||
const task = this.scheduler.nextTask(currentTs);
|
||||
|
||||
// текущего таска нет, очищаем очередь действий по таску
|
||||
if (!taskCommand) {
|
||||
if (!task) {
|
||||
this.logger.log('NO ACTIVE TASK');
|
||||
this.scheduler.clearActions();
|
||||
return;
|
||||
@ -54,26 +54,29 @@ export class Executor {
|
||||
|
||||
const actionCommand = this.scheduler.nextAction();
|
||||
|
||||
this.logger.log('CURRENT JOB', 'TASK', taskCommand, 'ACTION', actionCommand);
|
||||
this.logger.log('CURRENT JOB', 'TASK', task, 'ACTION', actionCommand);
|
||||
|
||||
this.runGrabbers();
|
||||
|
||||
try {
|
||||
if (actionCommand) {
|
||||
return await this.processActionCommand(actionCommand, taskCommand);
|
||||
return await this.processActionCommand(actionCommand, task);
|
||||
}
|
||||
|
||||
if (taskCommand) {
|
||||
return await this.processTaskCommand(taskCommand);
|
||||
if (task) {
|
||||
return await this.processTaskCommand(task);
|
||||
}
|
||||
} catch (e) {
|
||||
this.handleError(e);
|
||||
this.handleError(e, task);
|
||||
}
|
||||
}
|
||||
|
||||
private async processActionCommand(cmd: Command, task: Task) {
|
||||
const actionController = createAction(cmd.name, this.scheduler);
|
||||
this.logger.log('PROCESS ACTION', cmd.name, actionController);
|
||||
if (cmd.args.taskId !== task.id) {
|
||||
throw new ActionError(`Action task id ${cmd.args.taskId} not equal current task id ${task.id}`);
|
||||
}
|
||||
if (actionController) {
|
||||
await actionController.run(cmd.args, task);
|
||||
} else {
|
||||
@ -92,19 +95,19 @@ export class Executor {
|
||||
}
|
||||
}
|
||||
|
||||
private handleError(err: Error) {
|
||||
private handleError(err: Error, task: Task) {
|
||||
this.scheduler.clearActions();
|
||||
|
||||
if (err instanceof AbortTaskError) {
|
||||
this.logger.warn('ABORT TASK', err.taskId);
|
||||
this.scheduler.completeTask(err.taskId);
|
||||
this.logger.warn('ABORT TASK', task.id);
|
||||
this.scheduler.completeTask(task.id);
|
||||
this.scheduler.clearActions();
|
||||
return;
|
||||
}
|
||||
|
||||
if (err instanceof TryLaterError) {
|
||||
this.logger.warn('TRY', err.taskId, 'AFTER', err.seconds);
|
||||
this.scheduler.postponeTask(err.taskId, err.seconds);
|
||||
this.logger.warn('TRY', task.id, 'AFTER', err.seconds);
|
||||
this.scheduler.postponeTask(task.id, err.seconds);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user