Skip to content

Commit

Permalink
fix: indexing error regression (#1424)
Browse files Browse the repository at this point in the history
* fix: indexing error log detail regression

* chore: changeset

* fix: review, and handle trown objects that are not Errors

---------

Co-authored-by: typedarray <[email protected]>
  • Loading branch information
typedarray and typedarray authored Jan 8, 2025
1 parent 2292cf6 commit 60e7b6a
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 37 deletions.
5 changes: 5 additions & 0 deletions .changeset/unlucky-wasps-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ponder": patch
---

Fixed a bug where indexing errors did not include the block number and transaction hash of the event being indexed.
131 changes: 94 additions & 37 deletions packages/core/src/indexing/service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { IndexingFunctions } from "@/build/configAndIndexingFunctions.js";
import type { Common } from "@/common/common.js";
import { BaseError } from "@/common/errors.js";
import type { Network } from "@/config/networks.js";
import type { Schema } from "@/drizzle/index.js";
import type { IndexingStore } from "@/indexing-store/index.js";
Expand All @@ -10,6 +11,7 @@ import {
isAddressFactory,
} from "@/sync/source.js";
import type { Db } from "@/types/db.js";
import type { Block, Log, Trace, Transaction } from "@/types/eth.js";
import {
type Checkpoint,
decodeCheckpoint,
Expand Down Expand Up @@ -377,54 +379,32 @@ const executeSetup = async (
);
} catch (_error) {
if (indexingService.isKilled) return { status: "killed" };
const error = _error as Error;

const decodedCheckpoint = decodeCheckpoint(event.checkpoint);
const error = _error instanceof Error ? _error : new Error(String(_error));

addStackTrace(error, common.options);

common.metrics.ponder_indexing_has_error.set(1);
if (error instanceof BaseError) {
error.meta.push(toErrorMeta(event));
} else {
// @ts-expect-error
error.meta = [toErrorMeta(event)];
}

const decodedCheckpoint = decodeCheckpoint(event.checkpoint);
common.logger.error({
service: "indexing",
msg: `Error while processing '${event.name}' event in '${networkByChainId[event.chainId]!.name}' block ${decodedCheckpoint.blockNumber}`,
error,
});

common.metrics.ponder_indexing_has_error.set(1);

return { status: "error", error: error };
}

return { status: "success" };
};

const toErrorMeta = (event: Event) => {
switch (event.type) {
case "log":
case "trace": {
return `Event arguments:\n${prettyPrint(event.event.args)}`;
}

case "transfer": {
return `Event arguments:\n${prettyPrint(event.event.transfer)}`;
}

case "block": {
return `Block:\n${prettyPrint({
hash: event.event.block.hash,
number: event.event.block.number,
timestamp: event.event.block.timestamp,
})}`;
}

case "transaction": {
return `Transaction:\n${prettyPrint({
hash: event.event.transaction.hash,
block: event.event.block.number,
})}`;
}
}
};

const executeEvent = async (
indexingService: Service,
{ event }: { event: Event },
Expand Down Expand Up @@ -465,17 +445,19 @@ const executeEvent = async (
);
} catch (_error) {
if (indexingService.isKilled) return { status: "killed" };
const error = _error as Error & { meta?: string[] };

const decodedCheckpoint = decodeCheckpoint(event.checkpoint);
const error = _error instanceof Error ? _error : new Error(String(_error));

addStackTrace(error, common.options);

error.meta = Array.isArray(error.meta) ? error.meta : [];
if (error.meta.length === 0) {
if (error instanceof BaseError) {
error.meta.push(toErrorMeta(event));
} else {
// @ts-expect-error
error.meta = [toErrorMeta(event)];
}

const decodedCheckpoint = decodeCheckpoint(event.checkpoint);

common.logger.error({
service: "indexing",
msg: `Error while processing '${event.name}' event in '${networkByChainId[event.chainId]!.name}' block ${decodedCheckpoint.blockNumber}`,
Expand All @@ -489,3 +471,78 @@ const executeEvent = async (

return { status: "success" };
};

const blockText = (block: Block) =>
`Block:\n${prettyPrint({
hash: block.hash,
number: block.number,
timestamp: block.timestamp,
})}`;

const transactionText = (transaction: Transaction) =>
`Transaction:\n${prettyPrint({
hash: transaction.hash,
from: transaction.from,
to: transaction.to,
})}`;

const logText = (log: Log) =>
`Log:\n${prettyPrint({
index: log.logIndex,
address: log.address,
})}`;

const traceText = (trace: Trace) =>
`Trace:\n${prettyPrint({
traceIndex: trace.traceIndex,
from: trace.from,
to: trace.to,
})}`;

const toErrorMeta = (event: Event | SetupEvent) => {
switch (event.type) {
case "setup": {
return `Block:\n${prettyPrint({
number: event.block,
})}`;
}

case "log": {
return [
`Event arguments:\n${prettyPrint(event.event.args)}`,
logText(event.event.log),
transactionText(event.event.transaction),
blockText(event.event.block),
].join("\n");
}

case "trace": {
return [
`Call trace arguments:\n${prettyPrint(event.event.args)}`,
traceText(event.event.trace),
transactionText(event.event.transaction),
blockText(event.event.block),
].join("\n");
}

case "transfer": {
return [
`Transfer arguments:\n${prettyPrint(event.event.transfer)}`,
traceText(event.event.trace),
transactionText(event.event.transaction),
blockText(event.event.block),
].join("\n");
}

case "block": {
return blockText(event.event.block);
}

case "transaction": {
return [
transactionText(event.event.transaction),
blockText(event.event.block),
].join("\n");
}
}
};
4 changes: 4 additions & 0 deletions packages/core/src/utils/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ export function prettyPrint(
return [key, trimmedValue];
})
.filter(Boolean) as [string, string][];

if (entries.length === 0) return " (empty object)";

const maxLength = entries.reduce(
(acc, [key]) => Math.max(acc, key.length),
0,
);

return entries
.map(([key, value]) => ` ${`${key}`.padEnd(maxLength + 1)} ${value}`)
.join("\n");
Expand Down

0 comments on commit 60e7b6a

Please sign in to comment.