Change repository name and cretae error foulder (#819)

* Change repository name and cretae error foulder

* Rename SolanaFailure file

* Rename SolanaFailure file

---------

Co-authored-by: Julian Merlo <julianmerlo@MacBook-Pro-de-Julian.local>
This commit is contained in:
Julian 2023-11-24 13:03:48 -03:00 committed by GitHub
parent f29443d8b6
commit 1109c5d135
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 94 additions and 94 deletions

View File

@ -2,39 +2,3 @@ export * from "./evm";
export * from "./events"; export * from "./events";
export * from "./jobs"; export * from "./jobs";
export * as solana from "./solana"; export * as solana from "./solana";
export class Fallible<R, E> {
private error?: E;
private value?: R;
constructor(value?: R, error?: E) {
this.value = value;
this.error = error;
}
public getValue(): R {
if (!this.value) {
throw this.error ? this.error : new Error("No value and no error present");
}
return this.value;
}
public getError(): E {
if (!this.error) {
throw new Error("No error present");
}
return this.error;
}
public isOk(): boolean {
return !this.error && this.value !== undefined;
}
public static ok<R, E>(value: R): Fallible<R, E> {
return new Fallible<R, E>(value);
}
public static error<R, E>(error: E): Fallible<R, E> {
return new Fallible<R, E>(undefined, error);
}
}

View File

@ -59,28 +59,3 @@ export enum ErrorType {
SkippedSlot, SkippedSlot,
NoBlockOrBlockTime, NoBlockOrBlockTime,
} }
export class Failure extends Error {
readonly code?: number | unknown;
readonly type?: ErrorType;
constructor(code: number | unknown, message: string, type?: ErrorType) {
super(message);
this.code = code;
if (this.code === -32007 || this.code === -32009) {
this.type = ErrorType.SkippedSlot;
}
if (type) {
this.type = type;
}
}
public skippedSlot(): boolean {
return this.type === ErrorType.SkippedSlot;
}
public noBlockOrBlockTime(): boolean {
return this.type === ErrorType.NoBlockOrBlockTime;
}
}

View File

@ -0,0 +1,35 @@
export class Fallible<R, E> {
private value?: R;
private error?: E;
constructor(value?: R, error?: E) {
this.value = value;
this.error = error;
}
public getValue(): R {
if (!this.value) {
throw this.error ? this.error : new Error("No value and no error present");
}
return this.value;
}
public getError(): E {
if (!this.error) {
throw new Error("No error present");
}
return this.error;
}
public isOk(): boolean {
return !this.error && this.value !== undefined;
}
public static ok<R, E>(value: R): Fallible<R, E> {
return new Fallible<R, E>(value);
}
public static error<R, E>(error: E): Fallible<R, E> {
return new Fallible<R, E>(undefined, error);
}
}

View File

@ -0,0 +1,30 @@
export enum ErrorType {
SkippedSlot,
NoBlockOrBlockTime,
}
export class SolanaFailure extends Error {
readonly code?: number | unknown;
readonly type?: ErrorType;
constructor(code: number | unknown, message: string, type?: ErrorType) {
super(message);
this.code = code;
if (this.code === -32007 || this.code === -32009) {
this.type = ErrorType.SkippedSlot;
}
if (type) {
this.type = type;
}
}
public skippedSlot(): boolean {
return this.type === ErrorType.SkippedSlot;
}
public noBlockOrBlockTime(): boolean {
return this.type === ErrorType.NoBlockOrBlockTime;
}
}

View File

@ -0,0 +1,2 @@
export * from "./SolanaFailure";
export * from "./Fallible";

View File

@ -1,14 +1,7 @@
import { RunPollingJob } from "./actions/RunPollingJob"; import { RunPollingJob } from "./actions/RunPollingJob";
import { import { EvmBlock, EvmLog, EvmLogFilter, Handler, JobDefinition, solana } from "./entities";
EvmBlock,
EvmLog,
EvmLogFilter,
Fallible,
Handler,
JobDefinition,
solana,
} from "./entities";
import { ConfirmedSignatureInfo } from "./entities/solana"; import { ConfirmedSignatureInfo } from "./entities/solana";
import { Fallible, SolanaFailure } from "./errors";
export interface EvmBlockRepository { export interface EvmBlockRepository {
getBlockHeight(finality: string): Promise<bigint>; getBlockHeight(finality: string): Promise<bigint>;
@ -18,7 +11,7 @@ export interface EvmBlockRepository {
export interface SolanaSlotRepository { export interface SolanaSlotRepository {
getLatestSlot(commitment: string): Promise<number>; getLatestSlot(commitment: string): Promise<number>;
getBlock(slot: number, finality?: string): Promise<Fallible<solana.Block, solana.Failure>>; getBlock(slot: number, finality?: string): Promise<Fallible<solana.Block, SolanaFailure>>;
getSignaturesForAddress( getSignaturesForAddress(
address: string, address: string,
beforeSig: string, beforeSig: string,

View File

@ -5,13 +5,13 @@ import {
SnsEventRepository, SnsEventRepository,
EvmJsonRPCBlockRepository, EvmJsonRPCBlockRepository,
EvmJsonRPCBlockRepositoryCfg, EvmJsonRPCBlockRepositoryCfg,
FileMetadataRepo, FileMetadataRepository,
PromStatRepository, PromStatRepository,
StaticJobRepository, StaticJobRepository,
Web3SolanaSlotRepository, Web3SolanaSlotRepository,
} from "./repositories"; } from "./repositories";
import { HttpClient } from "./repositories/HttpClient"; import { HttpClient } from "./http/HttpClient";
import { JobRepository } from "../domain/repositories"; import { JobRepository } from "../domain/repositories";
export class RepositoriesBuilder { export class RepositoriesBuilder {
@ -31,7 +31,7 @@ export class RepositoriesBuilder {
this.repositories.set("metrics", new PromStatRepository()); this.repositories.set("metrics", new PromStatRepository());
this.cfg.metadata?.dir && this.cfg.metadata?.dir &&
this.repositories.set("metadata", new FileMetadataRepo(this.cfg.metadata.dir)); this.repositories.set("metadata", new FileMetadataRepository(this.cfg.metadata.dir));
this.cfg.supportedChains.forEach((chain) => { this.cfg.supportedChains.forEach((chain) => {
if (!this.cfg.platforms[chain]) throw new Error(`No config for chain ${chain}`); if (!this.cfg.platforms[chain]) throw new Error(`No config for chain ${chain}`);
@ -80,7 +80,7 @@ export class RepositoriesBuilder {
return this.getRepo("sns"); return this.getRepo("sns");
} }
public getMetadataRepository(): FileMetadataRepo { public getMetadataRepository(): FileMetadataRepository {
return this.getRepo("metadata"); return this.getRepo("metadata");
} }

View File

@ -2,7 +2,7 @@ import { EvmBlock, EvmLogFilter, EvmLog, EvmTag } from "../../domain/entities";
import { EvmBlockRepository } from "../../domain/repositories"; import { EvmBlockRepository } from "../../domain/repositories";
import { AxiosInstance } from "axios"; import { AxiosInstance } from "axios";
import winston from "../log"; import winston from "../log";
import { HttpClient, HttpClientError } from "./HttpClient"; import { HttpClient, HttpClientError } from "../http/HttpClient";
/** /**
* EvmJsonRPCBlockRepository is a repository that uses a JSON RPC endpoint to fetch blocks. * EvmJsonRPCBlockRepository is a repository that uses a JSON RPC endpoint to fetch blocks.

View File

@ -1,7 +1,7 @@
import fs from "fs"; import fs from "fs";
import { MetadataRepository } from "../../domain/repositories"; import { MetadataRepository } from "../../domain/repositories";
export class FileMetadataRepo implements MetadataRepository<any> { export class FileMetadataRepository implements MetadataRepository<any> {
private readonly dirPath: string; private readonly dirPath: string;
constructor(dirPath: string) { constructor(dirPath: string) {

View File

@ -15,13 +15,13 @@ import {
SolanaSlotRepository, SolanaSlotRepository,
StatRepository, StatRepository,
} from "../../domain/repositories"; } from "../../domain/repositories";
import { FileMetadataRepo, SnsEventRepository } from "./index"; import { FileMetadataRepository, SnsEventRepository } from "./index";
import { HandleSolanaTransactions } from "../../domain/actions/solana/HandleSolanaTransactions"; import { HandleSolanaTransactions } from "../../domain/actions/solana/HandleSolanaTransactions";
import { solanaLogMessagePublishedMapper, evmLogMessagePublishedMapper } from "../mappers"; import { solanaLogMessagePublishedMapper, evmLogMessagePublishedMapper } from "../mappers";
import log from "../log"; import log from "../log";
export class StaticJobRepository implements JobRepository { export class StaticJobRepository implements JobRepository {
private fileRepo: FileMetadataRepo; private fileRepo: FileMetadataRepository;
private dryRun: boolean = false; private dryRun: boolean = false;
private sources: Map<string, (def: JobDefinition) => RunPollingJob> = new Map(); private sources: Map<string, (def: JobDefinition) => RunPollingJob> = new Map();
private handlers: Map<string, (cfg: any, target: string, mapper: any) => Promise<Handler>> = private handlers: Map<string, (cfg: any, target: string, mapper: any) => Promise<Handler>> =
@ -45,7 +45,7 @@ export class StaticJobRepository implements JobRepository {
solanaSlotRepo: SolanaSlotRepository; solanaSlotRepo: SolanaSlotRepository;
} }
) { ) {
this.fileRepo = new FileMetadataRepo(path); this.fileRepo = new FileMetadataRepository(path);
this.blockRepoProvider = blockRepoProvider; this.blockRepoProvider = blockRepoProvider;
this.metadataRepo = repos.metadataRepo; this.metadataRepo = repos.metadataRepo;
this.statsRepo = repos.statsRepo; this.statsRepo = repos.statsRepo;

View File

@ -4,11 +4,11 @@ import {
PublicKey, PublicKey,
VersionedTransactionResponse, VersionedTransactionResponse,
SolanaJSONRPCError, SolanaJSONRPCError,
Finality,
} from "@solana/web3.js"; } from "@solana/web3.js";
import { Fallible, solana } from "../../domain/entities"; import { solana } from "../../domain/entities";
import { SolanaSlotRepository } from "../../domain/repositories"; import { SolanaSlotRepository } from "../../domain/repositories";
import { Fallible, SolanaFailure } from "../../domain/errors";
export class Web3SolanaSlotRepository implements SolanaSlotRepository { export class Web3SolanaSlotRepository implements SolanaSlotRepository {
connection: Connection; connection: Connection;
@ -21,7 +21,7 @@ export class Web3SolanaSlotRepository implements SolanaSlotRepository {
return this.connection.getSlot(commitment as Commitment); return this.connection.getSlot(commitment as Commitment);
} }
getBlock(slot: number, finality?: string): Promise<Fallible<solana.Block, solana.Failure>> { getBlock(slot: number, finality?: string): Promise<Fallible<solana.Block, SolanaFailure>> {
return this.connection return this.connection
.getBlock(slot, { .getBlock(slot, {
maxSupportedTransactionVersion: 0, maxSupportedTransactionVersion: 0,
@ -29,21 +29,21 @@ export class Web3SolanaSlotRepository implements SolanaSlotRepository {
}) })
.then((block) => { .then((block) => {
if (block === null) { if (block === null) {
return Fallible.error<solana.Block, solana.Failure>( return Fallible.error<solana.Block, SolanaFailure>(
new solana.Failure(0, "Block not found") new SolanaFailure(0, "Block not found")
); );
} }
return Fallible.ok<solana.Block, solana.Failure>({ return Fallible.ok<solana.Block, SolanaFailure>({
...block, ...block,
transactions: block.transactions.map((tx) => this.mapTx(tx, slot)), transactions: block.transactions.map((tx) => this.mapTx(tx, slot)),
}); });
}) })
.catch((err) => { .catch((err) => {
if (err instanceof SolanaJSONRPCError) { if (err instanceof SolanaJSONRPCError) {
return Fallible.error(new solana.Failure(err.code, err.message)); return Fallible.error(new SolanaFailure(err.code, err.message));
} }
return Fallible.error(new solana.Failure(0, err.message)); return Fallible.error(new SolanaFailure(0, err.message));
}); });
} }

View File

@ -7,7 +7,7 @@ if (!("toJSON" in BigInt.prototype)) {
}); });
} }
export * from "./FileMetadataRepo"; export * from "./FileMetadataRepository";
export * from "./SnsEventRepository"; export * from "./SnsEventRepository";
export * from "./EvmJsonRPCBlockRepository"; export * from "./EvmJsonRPCBlockRepository";
export * from "./PromStatRepository"; export * from "./PromStatRepository";

View File

@ -10,7 +10,8 @@ import {
StatRepository, StatRepository,
} from "../../../../src/domain/repositories"; } from "../../../../src/domain/repositories";
import { thenWaitForAssertion } from "../../../wait-assertion"; import { thenWaitForAssertion } from "../../../wait-assertion";
import { Fallible, solana } from "../../../../src/domain/entities"; import { solana } from "../../../../src/domain/entities";
import { Fallible } from "../../../../src/domain/errors";
let pollSolanaTransactions: PollSolanaTransactions; let pollSolanaTransactions: PollSolanaTransactions;
let cfg: PollSolanaTransactionsConfig; let cfg: PollSolanaTransactionsConfig;

View File

@ -3,7 +3,7 @@ import { EvmJsonRPCBlockRepository } from "../../../src/infrastructure/repositor
import axios from "axios"; import axios from "axios";
import nock from "nock"; import nock from "nock";
import { EvmLogFilter, EvmTag } from "../../../src/domain/entities"; import { EvmLogFilter, EvmTag } from "../../../src/domain/entities";
import { HttpClient } from "../../../src/infrastructure/repositories/HttpClient"; import { HttpClient } from "../../../src/infrastructure/http/HttpClient";
axios.defaults.adapter = "http"; // needed by nock axios.defaults.adapter = "http"; // needed by nock
const rpc = "http://localhost"; const rpc = "http://localhost";

View File

@ -1,10 +1,10 @@
import { describe, expect, it, beforeEach, afterEach } from "@jest/globals"; import { describe, expect, it, beforeEach, afterEach } from "@jest/globals";
import fs from "fs"; import fs from "fs";
import { FileMetadataRepo } from "../../../src/infrastructure/repositories"; import { FileMetadataRepository } from "../../../src/infrastructure/repositories";
describe("FileMetadataRepo", () => { describe("FileMetadataRepository", () => {
const dirPath = "./metadata-repo"; const dirPath = "./metadata-repo";
const repo = new FileMetadataRepo(dirPath); const repo = new FileMetadataRepository(dirPath);
beforeEach(() => { beforeEach(() => {
if (!fs.existsSync(dirPath)) { if (!fs.existsSync(dirPath)) {