Skip to content

Commit a91f392

Browse files
committed
Differentiate from missing and error in strategies
1 parent f64d848 commit a91f392

File tree

4 files changed

+44
-14
lines changed

4 files changed

+44
-14
lines changed

packages/transaction-decoder/src/abi-strategy/request-model.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ export class ResolveStrategyABIError {
1616
) {}
1717
}
1818

19+
export class MissingABIError {
20+
readonly _tag = 'MissingABIError'
21+
constructor(
22+
readonly address: string,
23+
readonly chainId: number,
24+
readonly strategyId: string,
25+
readonly event?: string,
26+
readonly signature?: string,
27+
readonly message: string = 'Missing contract ABI',
28+
) {}
29+
}
30+
1931
interface FunctionFragmentABI {
2032
type: 'func'
2133
abi: string
@@ -47,7 +59,7 @@ export interface ContractAbiResolverStrategy {
4759
type: 'address' | 'fragment'
4860
id: string
4961
rateLimit?: RateLimiterOptions
50-
resolver: (_: GetContractABIStrategyParams) => Effect.Effect<ContractABI[], ResolveStrategyABIError>
62+
resolver: (_: GetContractABIStrategyParams) => Effect.Effect<ContractABI[], ResolveStrategyABIError | MissingABIError>
5163
}
5264

5365
export interface GetContractABIStrategyParams {

packages/transaction-decoder/src/abi-strategy/strategy-executor.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Effect, Schedule, Duration, pipe, Data } from 'effect'
2-
import { GetContractABIStrategyParams, ContractAbiResolverStrategy } from '../abi-strategy/request-model.js'
2+
import { GetContractABIStrategyParams, ContractAbiResolverStrategy, MissingABIError } from './request-model.js'
33
import type { CircuitBreaker } from '../circuit-breaker/circuit-breaker.js'
44
import { RequestPool } from '../circuit-breaker/request-pool.js'
55
import * as Constants from '../circuit-breaker/constants.js'
@@ -23,15 +23,16 @@ export const make = (circuitBreaker: CircuitBreaker, requestPool: RequestPool) =
2323
Schedule.compose(Schedule.recurs(Constants.DEFAULT_RETRY_TIMES)),
2424
),
2525
),
26-
(effect) => circuitBreaker.withCircuitBreaker(strategy.id, effect),
27-
(effect) => requestPool.withPoolManagement(params.chainId, effect),
28-
Effect.catchAll((error) => {
26+
Effect.catchTag('MissingABIError', (error) => {
2927
// Log error but don't fail the entire operation
3028
return Effect.gen(function* () {
31-
yield* Effect.logWarning(`Strategy ${strategy.id} failed: ${JSON.stringify(error)}`)
32-
return yield* Effect.fail(error)
29+
yield* Effect.logWarning(`Strategy ${strategy.id} found no ABI: ${error.message}`)
30+
return yield* Effect.succeed(error)
3331
})
3432
}),
33+
(effect) => circuitBreaker.withCircuitBreaker(strategy.id, effect),
34+
(effect) => requestPool.withPoolManagement(params.chainId, effect),
35+
Effect.flatMap((data) => (data instanceof MissingABIError ? Effect.fail(data) : Effect.succeed(data))),
3536
)
3637
}
3738

packages/transaction-decoder/src/meta-strategy/request-model.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ export class ResolveStrategyMetaError {
1818
) {}
1919
}
2020

21+
export class MissingMetaError {
22+
readonly _tag = 'MissingMetaError'
23+
constructor(
24+
readonly address: Address,
25+
readonly chainId: number,
26+
readonly strategyId: string,
27+
readonly message: string = 'Missing contract metadata',
28+
) {}
29+
}
30+
2131
export interface ContractMetaResolverStrategy {
2232
id: string
2333
resolver: RequestResolver.RequestResolver<GetContractMetaStrategy, never>
@@ -32,6 +42,7 @@ export class GetContractMetaStrategy extends Schema.TaggedRequest<GetContractMet
3242
Schema.instanceOf(ResolveStrategyMetaError),
3343
Schema.instanceOf(UnknownNetwork),
3444
Schema.instanceOf(RPCFetchError),
45+
Schema.instanceOf(MissingMetaError),
3546
),
3647
success: SchemaContractData,
3748
payload: {

packages/transaction-decoder/src/meta-strategy/strategy-executor.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { Effect, Schedule, Duration, pipe, Data } from 'effect'
2-
import { FetchMetaParams, ContractMetaResolverStrategy, GetContractMetaStrategy } from './request-model.js'
2+
import {
3+
FetchMetaParams,
4+
ContractMetaResolverStrategy,
5+
GetContractMetaStrategy,
6+
MissingMetaError,
7+
} from './request-model.js'
38
import type { CircuitBreaker } from '../circuit-breaker/circuit-breaker.js'
49
import { RequestPool } from '../circuit-breaker/request-pool.js'
510
import * as Constants from '../circuit-breaker/constants.js'
@@ -31,15 +36,16 @@ export const make = (circuitBreaker: CircuitBreaker, requestPool: RequestPool) =
3136
Schedule.compose(Schedule.recurs(Constants.DEFAULT_RETRY_TIMES)),
3237
),
3338
),
34-
(effect) => circuitBreaker.withCircuitBreaker(strategy.id, effect),
35-
(effect) => requestPool.withPoolManagement(params.chainId, effect),
36-
Effect.catchAll((error) => {
37-
// Log error but don't fail the entire operation
39+
// Treate MissingMetaError as a success for circuit breaker
40+
Effect.catchTag('MissingMetaError', (error) => {
3841
return Effect.gen(function* () {
39-
yield* Effect.logWarning(`Meta strategy ${strategy.id} failed: ${JSON.stringify(error)}`)
40-
return yield* Effect.fail(error)
42+
yield* Effect.logWarning(`Meta strategy ${strategy.id} found no metadata: ${error.message}`)
43+
return yield* Effect.succeed(error)
4144
})
4245
}),
46+
(effect) => circuitBreaker.withCircuitBreaker(strategy.id, effect),
47+
(effect) => requestPool.withPoolManagement(params.chainId, effect),
48+
Effect.flatMap((data) => (data instanceof MissingMetaError ? Effect.fail(data) : Effect.succeed(data))),
4349
)
4450
}
4551

0 commit comments

Comments
 (0)