fix: handle object response from gen_call on testnet#147
Conversation
Testnet node returns gen_call results as an object with data, status, eqOutputs, stdout, stderr, and logs fields. Studio returns a bare hex string. extractGenCallResult() now handles both formats.
📝 WalkthroughWalkthroughThis PR refactors Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/contracts/actions.ts (2)
21-31: Consider defensive handling of potential0xprefix in response data.If
result(string) orobj.dataalready contains a0xprefix, this will produce0x0x...which would causefromHexto fail at line 111. While the current testnet/Studio APIs may not include the prefix, a defensive approach would be safer:🛡️ Proposed defensive fix
function extractGenCallResult(result: unknown): `0x${string}` { if (typeof result === "string") { - return `0x${result}` as `0x${string}`; + const hex = result.startsWith("0x") ? result.slice(2) : result; + return `0x${hex}` as `0x${string}`; } if (result && typeof result === "object" && "data" in result) { const obj = result as {data: string; status?: {code: number; message: string}}; if (obj.status && obj.status.code !== 0) { throw new Error(`gen_call failed: ${obj.status.message}`); } - return `0x${obj.data}` as `0x${string}`; + const hex = obj.data.startsWith("0x") ? obj.data.slice(2) : obj.data; + return `0x${hex}` as `0x${string}`; } throw new Error(`Unexpected gen_call response: ${JSON.stringify(result)}`); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/contracts/actions.ts` around lines 21 - 31, The extractGenCallResult function may double-prefix hex strings with "0x", so update it to defensively strip a leading "0x" if present before adding the single "0x" prefix; specifically, in the branches handling a plain string result and obj.data (in extractGenCallResult) trim any leading "0x"/"0X" and validate the underlying value is non-empty, then return `0x${cleaned}`; also add a final fallback to throw a clear error for unexpected result types so callers (e.g., code using fromHex) never receive a malformed hex string.
27-29: Add test coverage for the error path whengen_callreturns a non-zero status code.The error-throwing branch on lines 27-29 (
if (obj.status && obj.status.code !== 0)) is not covered by existing tests intests/contracts-actions.test.ts. Consider adding a test that mocks agen_callresponse with a failing status to verify the error message is properly thrown.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/contracts/actions.ts` around lines 27 - 29, Add a unit test in tests/contracts-actions.test.ts that exercises the error branch when gen_call returns a non-zero status: mock or stub the gen_call call (e.g., using jest.spyOn or a test double) to return an object like { status: { code: 1, message: 'some error' } }, call the function under test that invokes gen_call, and assert that it throws an Error with the message "gen_call failed: some error"; ensure the test targets the code path guarded by the check (obj.status && obj.status.code !== 0) so the throw in that branch is covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/contracts/actions.ts`:
- Around line 21-31: The extractGenCallResult function may double-prefix hex
strings with "0x", so update it to defensively strip a leading "0x" if present
before adding the single "0x" prefix; specifically, in the branches handling a
plain string result and obj.data (in extractGenCallResult) trim any leading
"0x"/"0X" and validate the underlying value is non-empty, then return
`0x${cleaned}`; also add a final fallback to throw a clear error for unexpected
result types so callers (e.g., code using fromHex) never receive a malformed hex
string.
- Around line 27-29: Add a unit test in tests/contracts-actions.test.ts that
exercises the error branch when gen_call returns a non-zero status: mock or stub
the gen_call call (e.g., using jest.spyOn or a test double) to return an object
like { status: { code: 1, message: 'some error' } }, call the function under
test that invokes gen_call, and assert that it throws an Error with the message
"gen_call failed: some error"; ensure the test targets the code path guarded by
the check (obj.status && obj.status.code !== 0) so the throw in that branch is
covered.
Summary
gen_callresults as an object{data, status, eqOutputs, stdout, stderr, logs}while Studio returns a bare hex string`0x${result}`which produced"0x[object Object]"on testnet, crashing viem'shexToBytesextractGenCallResult()that handles both response formatsget_balanceon0x73ee6af5F210d5AC8902B18F53CE23b53eDFC65Fnow returns correctly)Test plan
readContractworks against testnet-bradburySummary by CodeRabbit