Skip to content

Commit

Permalink
fix: error cleanup based on comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jahabeebs committed Sep 18, 2024
1 parent c13e0b7 commit 52099de
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 117 deletions.
6 changes: 2 additions & 4 deletions packages/automated-dispute/src/exceptions/errorFactory.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { CustomContractError } from "../exceptions/index.js";
import { ErrorHandlingStrategy, ErrorScenario } from "../types/index.js";
import { ErrorHandlingStrategy } from "../types/index.js";

const errorStrategies: Map<string, ErrorHandlingStrategy> = new Map([
//TODO: add all error strategies
[
"EBORequestCreator_InvalidEpoch",
{
scenario: ErrorScenario.Unrecoverable,
shouldNotify: true,
shouldTerminate: true,
shouldConsume: false,
Expand All @@ -20,9 +19,8 @@ export class ErrorFactory {

if (!strategy) {
return new CustomContractError(errorName, {
scenario: ErrorScenario.Unrecoverable,
shouldNotify: true,
shouldTerminate: true,
shouldTerminate: false,
shouldConsume: true,
});
}
Expand Down
18 changes: 1 addition & 17 deletions packages/automated-dispute/src/exceptions/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CustomContractError } from "../exceptions/index.js";
import { ErrorScenario, EventReactError } from "../types/index.js";
import { EventReactError } from "../types/index.js";

export class ErrorHandler {
public static async handle(error: CustomContractError, context: any): Promise<void> {
Expand Down Expand Up @@ -30,22 +30,6 @@ export class ErrorHandler {
context.consumeEvent();
}
}

switch (strategy.scenario) {
case ErrorScenario.Skippable:
console.info(`Skippable error: ${error.message}. Consuming the event.`);

break;
case ErrorScenario.Retryable:
console.warn(`Retryable error: ${error.message}. Will retry later.`);

break;
case ErrorScenario.Unrecoverable:
console.error(`Unrecoverable error: ${error.message}.`);
break;
default:
console.error(`Unknown error scenario: ${strategy.scenario}`);
}
}

private static async notifyError(error: CustomContractError, context: any): Promise<void> {
Expand Down
153 changes: 64 additions & 89 deletions packages/automated-dispute/src/services/eboActor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@ import type {
} from "../types/index.js";
import { ErrorHandler } from "../exceptions/ErrorHandler.js";
import {
CustomContractError,
DisputeWithoutResponse,
EBORequestCreator_ChainNotAdded,
EBORequestCreator_InvalidEpoch,
EBORequestModule_InvalidRequester,
ErrorFactory,
InvalidActorState,
InvalidDisputeStatus,
Oracle_InvalidRequestBody,
PastEventEnqueueError,
RequestMismatch,
ResponseAlreadyProposed,
Expand All @@ -40,7 +37,6 @@ import {
UpdateDisputeStatus,
} from "../services/index.js";
import { ActorRequest } from "../types/actorRequest.js";
import { ErrorScenario } from "../types/index.js";

/**
* Compare function to sort events chronologically in ascending order by block number
Expand Down Expand Up @@ -150,41 +146,17 @@ export class EboActor {
await this.onLastEvent(event);
}
} catch (err) {
if (err instanceof ContractFunctionRevertedError) {
// TODO: Add all errors appropriately -- this is boilerplate
const customError = ErrorFactory.createError(err.name)
.setContext({ event, registry: this.registry })
.on("BondEscalationModule_ShouldBeEscalated", async (context) => {
await this.protocolProvider.escalateDispute(
context.request.prophetData,
context.response.prophetData,
context.dispute.prophetData,
);
});

await ErrorHandler.handle(customError, {
consumeEvent: () => {
// TODO: consume logic
},
reenqueueEvent: () => {
if (event) {
this.eventsQueue.push(event);
}
},
terminateActor: () => {
// TODO: correct termination logic
this.registry.removeRequest(this.actorRequest.id);
},
});

if (customError.strategy.scenario === ErrorScenario.Unrecoverable) {
updateStateCommand.undo();
throw customError;
}
} else {
// For other errors, rethrow
this.logger.error(`Error processing event ${event.name}: ${err}`);

this.eventsQueue.push(event);
updateStateCommand.undo();

if (err instanceof CustomContractError && err.strategy.shouldTerminate) {
// Rethrow for EboProcessor to handle
throw err;
}

return;
}
}
});
Expand Down Expand Up @@ -292,26 +264,7 @@ export class EboActor {
* @param blockNumber block number to check open/closed windows
*/
public async onLastBlockUpdated(blockNumber: bigint): Promise<void> {
try {
await this.settleDisputes(blockNumber);
} catch (err) {
if (err instanceof ContractFunctionRevertedError) {
const customError = ErrorFactory.createError(err.name).setContext({
blockNumber,
registry: this.registry,
});

await ErrorHandler.handle(customError, {
terminateActor: () => {
// TODO: correct termination logic
this.registry.removeRequest(this.actorRequest.id);
},
});
} else {
throw err;
}
}

await this.settleDisputes(blockNumber);
const request = this.getActorRequest();
const proposalDeadline = request.prophetData.responseModuleData.deadline;
const isProposalWindowOpen = blockNumber <= proposalDeadline;
Expand Down Expand Up @@ -340,10 +293,7 @@ export class EboActor {
});

await ErrorHandler.handle(customError, {
terminateActor: () => {
// TODO: correct termination logic
this.registry.removeRequest(this.actorRequest.id);
},
//TODO: error logic
});
} else {
throw err;
Expand All @@ -360,29 +310,46 @@ export class EboActor {
* @param blockNumber block number to check if the dispute is to be settled
*/
private async settleDisputes(blockNumber: bigint): Promise<void> {
const request = this.getActorRequest();
const disputes: Dispute[] = this.getActiveDisputes();
try {
const request = this.getActorRequest();
const disputes: Dispute[] = this.getActiveDisputes();

const settledDisputes = disputes.map(async (dispute) => {
const responseId = dispute.prophetData.responseId;
const response = this.registry.getResponse(responseId);
const settledDisputes = disputes.map(async (dispute) => {
const responseId = dispute.prophetData.responseId;
const response = this.registry.getResponse(responseId);

if (!response) {
this.logger.error(
`While trying to settle dispute ${dispute.id} its response with` +
`id ${dispute.prophetData.responseId} was not found in the registry.`,
);
if (!response) {
this.logger.error(
`While trying to settle dispute ${dispute.id}, its response with ` +
`id ${dispute.prophetData.responseId} was not found in the registry.`,
);

throw new DisputeWithoutResponse(dispute);
}
throw new DisputeWithoutResponse(dispute);
}

if (this.canBeSettled(request, dispute, blockNumber)) {
await this.settleDispute(request, response, dispute);
}
});
if (this.canBeSettled(request, dispute, blockNumber)) {
await this.settleDispute(request, response, dispute);
}
});

// Any of the disputes not being handled correctly should make the actor fail
await Promise.all(settledDisputes);
await Promise.all(settledDisputes);
} catch (err) {
if (err instanceof ContractFunctionRevertedError) {
const customError = ErrorFactory.createError(err.name).setContext({
blockNumber,
registry: this.registry,
});

await ErrorHandler.handle(customError, {
terminateActor: () => {
// TODO: correct termination logic
this.registry.removeRequest(this.actorRequest.id);
},
});
} else {
throw err;
}
}
}

private getActiveDisputes(): Dispute[] {
Expand Down Expand Up @@ -557,15 +524,23 @@ export class EboActor {
try {
await this.proposeResponse(chainId);
} catch (err) {
if (err instanceof ResponseAlreadyProposed) this.logger.info(err.message);
else if (err instanceof EBORequestCreator_InvalidEpoch) {
// TODO: Handle error
} else if (err instanceof Oracle_InvalidRequestBody) {
// TODO: Handle error
} else if (err instanceof EBORequestModule_InvalidRequester) {
// TODO: Handle error
} else if (err instanceof EBORequestCreator_ChainNotAdded) {
// TODO: Handle error
if (err instanceof ContractFunctionRevertedError) {
const customError = ErrorFactory.createError(err.name)
.setContext({ event, registry: this.registry })
.on("ErrorName", async (context) => {
console.log(context);
});

await ErrorHandler.handle(customError, {
reenqueueEvent: () => {
this.eventsQueue.push(event);
},
});

if (customError.strategy.shouldTerminate) {
// Rethrow for EboProcessor to handle
throw customError;
}
} else {
throw err;
}
Expand Down
7 changes: 0 additions & 7 deletions packages/automated-dispute/src/types/errorTypes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
export enum ErrorScenario {
Skippable = "Skippable",
Retryable = "Retryable",
Unrecoverable = "Unrecoverable",
}

export type BaseErrorStrategy = {
scenario: ErrorScenario;
shouldNotify: boolean;
shouldTerminate: boolean;
shouldConsume: boolean;
Expand Down

0 comments on commit 52099de

Please sign in to comment.