Skip to content

Commit

Permalink
chore(sdk): Make the "error handler" give more information (#777)
Browse files Browse the repository at this point in the history
  • Loading branch information
alainncls committed Nov 8, 2024
1 parent 6fd6a63 commit a4f049d
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 50 deletions.
2 changes: 1 addition & 1 deletion sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@verax-attestation-registry/verax-sdk",
"version": "2.1.2",
"version": "2.1.3",
"description": "Verax Attestation Registry SDK to interact with the subgraph and the contracts",
"keywords": [
"linea-attestation-registry",
Expand Down
41 changes: 9 additions & 32 deletions sdk/src/utils/errorHandler.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BaseError, ContractFunctionRevertedError, Abi } from "viem";
import { handleError, extractErrorName } from "./errorHandler";
import { Abi, BaseError, ContractFunctionRevertedError } from "viem";
import { handleError } from "./errorHandler";
import { ActionType } from "./constants";

describe("errorHandler", () => {
Expand All @@ -13,7 +13,7 @@ describe("errorHandler", () => {
},
];

const mockBaseError = new BaseError("Base error");
const mockBaseError = new BaseError("This is a BaseError");
const mockRevertedError = new ContractFunctionRevertedError({
abi: mockAbi,
functionName: "myFunction",
Expand All @@ -30,29 +30,6 @@ describe("errorHandler", () => {
jest.clearAllMocks();
});

describe("extractErrorName", () => {
it("should return errorName if it exists in revertError.data", () => {
const errorName = extractErrorName(mockRevertedError);
expect(errorName).toBe("MockErrorName");
});

it("should return the signature if errorName is undefined", () => {
(mockRevertedError.data as Partial<typeof mockRevertedError.data>).errorName = undefined;
mockRevertedError.signature = "myFunction(uint256)" as `0x${string}`;

const errorName = extractErrorName(mockRevertedError);
expect(errorName).toBe("myFunction(uint256)");
});

it("should return 'unknown revert reason' if both errorName and signature are undefined", () => {
(mockRevertedError.data as Partial<typeof mockRevertedError.data>).errorName = undefined;
mockRevertedError.signature = undefined;

const errorName = extractErrorName(mockRevertedError);
expect(errorName).toBe("unknown revert reason");
});
});

describe("handleError", () => {
const actionType: ActionType = ActionType.Transaction;

Expand All @@ -61,7 +38,7 @@ describe("errorHandler", () => {
jest.spyOn(mockBaseErrorWithoutShortMessage, "walk").mockImplementation(() => null);

expect(() => handleError(actionType, mockBaseErrorWithoutShortMessage)).toThrow(
`${actionType} failed with Base error`,
`${actionType} failed: Base error`,
);
});

Expand All @@ -73,7 +50,7 @@ describe("errorHandler", () => {
return fn(mockRevertedError) ? mockRevertedError : null;
});

expect(() => handleError(actionType, mockBaseError)).toThrow(`${actionType} failed with myFunction(uint256)`);
expect(() => handleError(actionType, mockBaseError)).toThrow(`${actionType} failed: myFunction(uint256)`);
});

it("should throw 'unknown revert reason' if both errorName and signature are undefined", () => {
Expand All @@ -84,7 +61,7 @@ describe("errorHandler", () => {
return fn(mockRevertedError) ? mockRevertedError : null;
});

expect(() => handleError(actionType, mockBaseError)).toThrow(`${actionType} failed with unknown revert reason`);
expect(() => handleError(actionType, mockBaseError)).toThrow(`${actionType} failed: unknown revert reason`);
});

it("should throw with shortMessage if error is a BaseError but not ContractFunctionRevertedError", () => {
Expand All @@ -97,20 +74,20 @@ describe("errorHandler", () => {
jest.spyOn(mockBaseErrorWithShortMessage, "walk").mockImplementation(() => null);

expect(() => handleError(actionType, mockBaseErrorWithShortMessage)).toThrow(
`${actionType} failed with ${shortMessage}`,
`${actionType} failed: ${shortMessage}`,
);
});

it("should throw with the error message if error is a native JavaScript Error", () => {
const nativeError = new Error("Native error message");

expect(() => handleError(actionType, nativeError)).toThrow(`${actionType} failed with Native error message`);
expect(() => handleError(actionType, nativeError)).toThrow(`${actionType} failed: Native error message`);
});

it("should throw 'unknown error' if the error is not an instance of BaseError or Error", () => {
const unknownError = { message: "Some unknown error" };

expect(() => handleError(actionType, unknownError)).toThrow(`${actionType} failed with an unknown error`);
expect(() => handleError(actionType, unknownError)).toThrow(`${actionType} failed: An unknown error occurred`);
});
});
});
26 changes: 9 additions & 17 deletions sdk/src/utils/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import { BaseError, ContractFunctionRevertedError } from "viem";
import { ActionType } from "./constants";

export function extractErrorName(revertError: ContractFunctionRevertedError): string {
if (revertError.data?.errorName) {
return revertError.data.errorName;
function getErrorMessage(type: ActionType, err: BaseError): string {
const revertError = err.walk((e) => e instanceof ContractFunctionRevertedError);
if (revertError instanceof ContractFunctionRevertedError) {
const errorName = revertError.data?.errorName || revertError.signature || "unknown revert reason";
return `${type} failed: ${errorName}`;
}
if (revertError.signature) {
return revertError.signature;
}
return "unknown revert reason";
return `${type} failed: ${err.shortMessage || "An unknown error occurred"}`;
}

export function handleError(type: ActionType, err: unknown): never {
if (err instanceof BaseError) {
const revertError = err.walk((err) => err instanceof ContractFunctionRevertedError);
if (revertError instanceof ContractFunctionRevertedError) {
const errorName = extractErrorName(revertError);
throw new Error(`${type} failed with ${errorName}`);
} else {
const errorMessage = err.shortMessage ?? "An unknown error occurred";
throw new Error(`${type} failed with ${errorMessage}`);
}
throw new Error(getErrorMessage(type, err));
} else if (err instanceof Error) {
throw new Error(`${type} failed with ${err.message}`);
throw new Error(`${type} failed: ${err.message}`);
} else {
throw new Error(`${type} failed with an unknown error`);
throw new Error(`${type} failed: An unknown error occurred`);
}
}

0 comments on commit a4f049d

Please sign in to comment.