Skip to content

feat: enhance axios shim error handling and add comprehensive tests#6349

Open
Pragadesh-45 wants to merge 4 commits intousebruno:mainfrom
Pragadesh-45:fix/6342
Open

feat: enhance axios shim error handling and add comprehensive tests#6349
Pragadesh-45 wants to merge 4 commits intousebruno:mainfrom
Pragadesh-45:fix/6342

Conversation

@Pragadesh-45
Copy link
Contributor

@Pragadesh-45 Pragadesh-45 commented Dec 8, 2025

Jira

fixes: #6342

Description

  • refactor: improve error handling in axios shim to include detailed error information such as response and config data
  • add: implement extensive unit tests for axios shim covering successful requests, error handling, and real-world scenarios
  • test: ensure proper handling of various HTTP status codes and network errors in the tests
    feat: improve serialization of error objects to handle circular references
  • add: implement a replacer function to enhance JSON serialization of error objects, preventing circular reference issues and preserving error properties
  • refactor: apply similar serialization logic in both ErrorCapture and utility functions for consistency
  • tests

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.

Before:
image

After:
image
image

Summary by CodeRabbit

  • Bug Fixes

    • Improved HTTP error handling: failures now reject with richer error details (message, isAxiosError, response status/statusText/headers/data, and request config) so callers receive complete error context.
    • Safer error serialization: captures Error-like objects (including nested/circular structures) more reliably during reporting.
  • Tests

    • Added comprehensive tests covering successful requests, 4xx/5xx errors, network/timeouts, base-client behavior, and cross-context error propagation.
  • Chores

    • No changes to public/exported API signatures.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Walkthrough

Changed the QuickJS axios shim to reject promises on errors and return a richer error object (message, code, isAxiosError, optional response: status/statusText/headers/data, and request config: url/method/headers/data) instead of resolving with minimal error info; added tests and updated ErrorCapture serialization.

Changes

Cohort / File(s) Summary
Axios shim (error handling)
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js
Added buildAxiosErrorData(err) to assemble full axios-like error payloads; replaced prior promise.resolve(...) error branches with promise.reject(marshallToVm(cleanJson(buildAxiosErrorData(err)), vm)) so errors propagate as rejections across the VM boundary.
Tests (new)
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js
New Jest suite mocking axios and exercising the QuickJS shim: success paths (get/post/all methods), 4xx/5xx responses, network errors, timeouts, base axios usage, and a real-world issue scenario; validates marshalled error shape across VM.
Error serialization
packages/bruno-app/src/components/ErrorCapture/index.js
Replaced bespoke Error branch with a generalized JSON replacer using a WeakSet circular guard; serializes Error-like objects by copying own properties so nested/circular structures and non-primitive values are safely stringified.

Sequence Diagram(s)

sequenceDiagram
  actor SandboxScript
  participant QuickJSVM
  participant Shim
  participant Axios
  SandboxScript->>QuickJSVM: invoke axios method (e.g., post)
  QuickJSVM->>Shim: call shim function with args
  Shim->>Axios: perform HTTP call
  Axios-->>Shim: success response OR error (network/4xx/5xx/timeout)
  alt success
    Shim-->>QuickJSVM: marshallToVm(cleanJson(response)) (promise resolved)
    QuickJSVM-->>SandboxScript: returns resolved data
  else error
    Shim-->>QuickJSVM: marshallToVm(cleanJson(buildAxiosErrorData(err))) (promise rejected)
    QuickJSVM-->>SandboxScript: throws / rejects with rich error object
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

size/L

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno

Poem

🔧 Once errors were quiet, resolved in the night,
Now they wake up, clear-eyed, and fully in sight.
Status, headers, config — each truth on display,
QuickJS and axios now speak plain by day. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main changes: enhancing axios shim error handling and adding comprehensive tests.
Linked Issues check ✅ Passed The PR fully addresses issue #6342 by implementing proper error rejection, preserving axios error properties (message, config, response, isAxiosError, code), and adding comprehensive test coverage.
Out of Scope Changes check ✅ Passed The ErrorCapture changes improve error serialization in the logging system, which directly supports the PR's goal of surfacing complete error details through Bruno's error handling pipeline.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4016754 and 903f26c.

📒 Files selected for processing (2)
  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js (2 hunks)
  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js
  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js
🧠 Learnings (1)
📚 Learning: 2025-12-05T20:31:33.005Z
Learnt from: CR
Repo: usebruno/bruno PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-05T20:31:33.005Z
Learning: Applies to **/*.test.{js,jsx,ts,tsx} : Add tests for any new functionality or meaningful changes. If code is added, removed, or significantly modified, corresponding tests should be updated or created

Applied to files:

  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js
🧬 Code graph analysis (1)
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js (2)
packages/bruno-js/src/sandbox/quickjs/utils/index.js (1)
  • marshallToVm (1-31)
packages/bruno-js/src/utils.js (1)
  • cleanJson (144-194)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: CLI Tests
  • GitHub Check: Unit Tests
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
🔇 Additional comments (6)
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js (1)

17-38: LGTM! Error handling now properly rejects with comprehensive error data.

The enhanced error structure correctly includes message, response details (status, statusText, headers, data), and request config, fixing issue #6342 where the shim was resolving on 4xx/5xx responses.

packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js (5)

22-107: LGTM! Comprehensive coverage of successful request scenarios.

The tests properly validate data marshalling across the VM boundary and ensure all HTTP methods work correctly. Handle disposal is consistent throughout.


109-252: LGTM! Thorough validation of 4xx/5xx error rejection behavior.

These tests confirm the fix for issue #6342, ensuring errors are properly rejected with comprehensive error data including response details and request config.


254-332: LGTM! Network error scenarios are well covered.

The tests validate that errors without responses (network failures, timeouts) still provide the error message and config data to callers.


334-411: LGTM! Base axios function coverage ensures API consistency.

The tests confirm that calling axios() directly behaves identically to the method shortcuts for both success and error cases.


413-472: LGTM! Excellent real-world scenario validation.

This test directly addresses the token refresh use case from issue #6342, ensuring that authentication error handling patterns work as expected with full error details preserved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js (1)

7-27: Helper correctly centralizes error shaping; consider exposing a bit more Axios metadata

buildAxiosErrorData does the right thing for message, response, and config, and nicely de-duplicates the logic. If you want closer parity with typical Axios errors, you might optionally also pass through lightweight fields such as err.code and err.isAxiosError (and maybe name) so existing guards like if (error.isAxiosError) keep working across environments.

Example (non-breaking) extension:

 const buildAxiosErrorData = (err) => {
   return {
     message: err.message,
+    code: err.code,
+    isAxiosError: err.isAxiosError,
     ...(err.response && {
       response: {
         status: err.response.status,
         statusText: err.response.statusText,
         headers: err.response.headers,
         data: err.response.data
       }
     }),
     ...(err.config && {
       config: {
         url: err.config.url,
         method: err.config.method,
         headers: err.config.headers,
         data: err.config.data
       }
     })
   };
 };
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js (1)

53-66: Consider a small helper to DRY the QuickJS async eval pattern

Most tests repeat the same boilerplate to run async code in the VM, resolve the promise, dump the value, and dispose handles. A tiny helper would make the intent clearer and reduce chances of mistakes if this pattern evolves.

For example:

const evalAsyncInVm = async (vm, code) => {
  const result = vm.evalCode(code);
  const promiseHandle = vm.unwrapResult(result);
  const resolvedResult = await vm.resolvePromise(promiseHandle);
  const resolvedHandle = vm.unwrapResult(resolvedResult);
  const value = vm.dump(resolvedHandle);

  resolvedHandle.dispose();
  promiseHandle.dispose();

  return value;
};

Then each test can do:

const responseData = await evalAsyncInVm(vm, `
  (async () => {
    const response = await axios.get('https://api.example.com/data');
    return response;
  })()
`);

This keeps the tests focused on behavior (status, data, error shape) instead of VM plumbing.

Also applies to: 82-95, 112-125, 168-175, 217-224, 262-269, 304-311, 343-350, 374-381, 421-428, 478-485

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 903f26c and f41e92a.

📒 Files selected for processing (2)
  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js (3 hunks)
  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings. For JSX/TSX attributes, use double quotes (e.g., )
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single params
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js
  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js
🧠 Learnings (1)
📚 Learning: 2025-12-05T20:31:33.005Z
Learnt from: CR
Repo: usebruno/bruno PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-05T20:31:33.005Z
Learning: Applies to **/*.test.{js,jsx,ts,tsx} : Add tests for any new functionality or meaningful changes. If code is added, removed, or significantly modified, corresponding tests should be updated or created

Applied to files:

  • packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js
🧬 Code graph analysis (1)
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js (2)
packages/bruno-js/src/sandbox/quickjs/utils/index.js (1)
  • marshallToVm (1-31)
packages/bruno-js/src/utils.js (1)
  • cleanJson (144-194)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: Unit Tests
  • GitHub Check: CLI Tests
🔇 Additional comments (3)
packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.js (1)

40-41: Rejection semantics and error marshalling now align with Axios expectations

Switching the .catch paths to promise.reject(marshallToVm(cleanJson(buildAxiosErrorData(err)), vm)) for both method shims and the base axios shim fixes the original problem: 4xx/5xx and other Axios errors now surface as rejections with rich response and config data available in the sandbox. The marshalling pipeline (buildAxiosErrorDatacleanJsonmarshallToVm) looks consistent with the success path and should behave well for binary-safe payloads.

Also applies to: 56-57

packages/bruno-js/src/sandbox/quickjs/shims/lib/axios.spec.js (2)

22-42: VM and module cleanup look correct and address leak concerns

The afterEach/afterAll hooks that dispose of vm and module (with guarded try/catch and nulling the references) nicely close the lifecycle gap from earlier reviews and should prevent QuickJS contexts and the underlying WASM module from leaking across tests.


1-8: [rewritten comment]
[classification_tag]

* refactor: improve error handling in axios shim to include detailed error information such as response and config data
* add: implement extensive unit tests for axios shim covering successful requests, error handling, and real-world scenarios
* test: ensure proper handling of various HTTP status codes and network errors in the tests
…ties

* add: include error code and isAxiosError flag in the error object returned by the axios shim for improved error handling
…ences

* add: implement a replacer function to enhance JSON serialization of error objects, preventing circular reference issues and preserving error properties
* refactor: apply similar serialization logic in both ErrorCapture and utility functions for consistency
* tests
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/bruno-app/src/components/ErrorCapture/index.js`:
- Around line 46-52: The serialized error object created in the ErrorCapture
code (the block using Object.getOwnPropertyNames on value) can miss the
Error.name because it's on the prototype; update the serialization to ensure
name is preserved by adding a fallback after copying properties: if error.name
is falsy, set it from value.name or value.constructor?.name (or a default like
'Error') so the error type is retained in payloads. Target the same block that
builds the local error object from value.
🧹 Nitpick comments (1)
packages/bruno-app/src/components/ErrorCapture/index.js (1)

35-36: Add JSDoc for serializeArgs to document serialization rules.

This abstraction now handles circular refs and Error normalization; adding JSDoc keeps the contract clear.

📝 Proposed JSDoc
+/**
+ * Serializes console error arguments into JSON-safe values.
+ * Handles circular references and Error-like objects.
+ * `@param` {any[]} args
+ * `@returns` {Array<any>}
+ */
 const serializeArgs = (args) => {
As per coding guidelines: Add JSDoc comments to abstractions for additional details.

Comment on lines +46 to +52
if (value instanceof Error || Object.prototype.toString.call(value) === '[object Error]' || (typeof value.message === 'string' && typeof value.stack === 'string')) {
const error = {};
Object.getOwnPropertyNames(value).forEach((prop) => {
error[prop] = value[prop];
});
return error;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Preserve Error.name in serialized payloads.

Object.getOwnPropertyNames skips the prototype name on standard Error instances, so logs lose the error type. Add a fallback copy.

🐛 Proposed fix
         if (value instanceof Error || Object.prototype.toString.call(value) === '[object Error]' || (typeof value.message === 'string' && typeof value.stack === 'string')) {
           const error = {};
           Object.getOwnPropertyNames(value).forEach((prop) => {
             error[prop] = value[prop];
           });
+          if (typeof value.name === 'string' && error.name === undefined) {
+            error.name = value.name;
+          }
           return error;
         }
🤖 Prompt for AI Agents
In `@packages/bruno-app/src/components/ErrorCapture/index.js` around lines 46 -
52, The serialized error object created in the ErrorCapture code (the block
using Object.getOwnPropertyNames on value) can miss the Error.name because it's
on the prototype; update the serialization to ensure name is preserved by adding
a fallback after copying properties: if error.name is falsy, set it from
value.name or value.constructor?.name (or a default like 'Error') so the error
type is retained in payloads. Target the same block that builds the local error
object from value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Axios shim is resolving on API 4xx or 5xx

1 participant