Skip to content

fix(button): error occurs with in Button click handler cannot be caught#5834

Open
zvn2060 wants to merge 2 commits intonuxt:v4from
zvn2060:fix/3237
Open

fix(button): error occurs with in Button click handler cannot be caught#5834
zvn2060 wants to merge 2 commits intonuxt:v4from
zvn2060:fix/3237

Conversation

@zvn2060
Copy link
Copy Markdown

@zvn2060 zvn2060 commented Jan 8, 2026

🔗 Linked issue

Resolves #3237

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

  • Fixed an issue where errors thrown inside the Button click handler cannot be caught by Vue’s onErrorCaptured hook.
  • Ensured the handler now re-throws within Vue’s async boundary so global error capturing and fallback UI continue to work as expected.
  • Added testcase to prevent future silent failures.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jan 8, 2026

npm i https://pkg.pr.new/@nuxt/ui@5834

commit: f592b21

@zvn2060 zvn2060 changed the title fix(button): error occurss with in Button click handler cannot be caught fix(button): error occurs with in Button click handler cannot be caught Jan 13, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 14, 2026

📝 Walkthrough

Walkthrough

The changes modify the Button component to properly handle asynchronous errors in click event handlers by wrapping the click handler with Vue's callWithAsyncErrorHandling utility. This ensures errors thrown during async click operations are propagated through Vue's error boundary system. A test case is added to verify that promise rejections from button clicks are captured by Vue's errorCaptured hook, validating the error handling behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change - fixing error handling in Button click handlers to work with Vue's error catching.
Description check ✅ Passed The description clearly explains the bug fix, the solution approach, and confirms a test was added to prevent regressions.
Linked Issues check ✅ Passed The PR successfully addresses the linked issue #3237 by wrapping the click handler with Vue's error handling mechanism to ensure errors are properly propagated to onErrorCaptured hooks.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the error handling issue: Button component modification and corresponding test case addition.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

You can customize the tone of the review comments and chat replies.

Configure the tone_instructions setting to customize the tone of the review comments and chat replies. For example, you can set the tone to Act like a strict teacher, Act like a pirate and more.

Copy link
Copy Markdown
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

🧹 Nitpick comments (1)
test/components/Button.spec.ts (1)

50-76: Good test coverage for the error handling fix.

The test correctly verifies that async errors from click handlers are captured by Vue's onErrorCaptured hook. A couple of minor suggestions:

  1. Line 52: Consider using a more specific type than any for the reject function
  2. Line 60: The semicolon after the function declaration is unnecessary
🔧 Optional cleanup
-  test('error occurs in click handler can be caught by Vue errorCaptured hook', async () => {
+  test('error in click handler is caught by Vue errorCaptured hook', async () => {
     const spyFn = vi.fn(() => false)
-    let reject: any | null = null
+    let reject: ((reason: Error) => void) | null = null
     const wrapper = await mountSuspended({
       components: { Button },
       setup() {
         function onClick() {
           return new Promise<void>((_, rej) => {
             reject = rej
           })
-        };
+        }
 
         onErrorCaptured(spyFn)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/components/Button.spec.ts` around lines 50 - 76, The test declares
reject as a loosely typed any and has an unnecessary semicolon after the onClick
function; update the reject variable to a precise function type such as let
reject: ((reason?: unknown) => void) | null (or a PromiseReject type) and remove
the trailing semicolon after the onClick() function declaration in the test that
mounts Button (references: reject variable, onClick function, mountSuspended,
onErrorCaptured, spyFn) so the code is typed correctly and the stray semicolon
is cleaned up.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/runtime/components/Button.vue`:
- Line 46: The file imports Vue internals callWithAsyncErrorHandling and
ErrorCodes — remove those imports and any usage of them (references to
callWithAsyncErrorHandling and ErrorCodes) from the Button component, and
instead use public-safe patterns: either wrap your click handler (e.g., the
component's onClick/handleClick method) in a simple try/catch for async errors
or rely on Vue's normal template event handling so errors propagate to app-level
handlers; keep only public imports (computed, ref, inject) and update any
error-handling logic to use try/catch or emit an error event rather than calling
Vue internal APIs.
- Line 136: Replace the undocumented `$` component reference passed into
callWithAsyncErrorHandling with a valid ComponentInternalInstance or null:
update the `@click` invocation that currently calls
callWithAsyncErrorHandling(onClickWrapper, $,
ErrorCodes.COMPONENT_EVENT_HANDLER, [$event]) to pass null (or obtain the actual
internal instance if available) so the second argument matches the required
type; then make error handling consistent with LinkBase.vue by ensuring
LinkBase's direct onClick invocations also wrap handlers with
callWithAsyncErrorHandling (or have Button delegate to LinkBase only after
wrapping), referencing the onClickWrapper function and
callWithAsyncErrorHandling to locate the changes.

---

Nitpick comments:
In `@test/components/Button.spec.ts`:
- Around line 50-76: The test declares reject as a loosely typed any and has an
unnecessary semicolon after the onClick function; update the reject variable to
a precise function type such as let reject: ((reason?: unknown) => void) | null
(or a PromiseReject type) and remove the trailing semicolon after the onClick()
function declaration in the test that mounts Button (references: reject
variable, onClick function, mountSuspended, onErrorCaptured, spyFn) so the code
is typed correctly and the stray semicolon is cleaned up.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5e6f3876-8ab7-4523-9550-7148f5b43589

📥 Commits

Reviewing files that changed from the base of the PR and between 9544d85 and 6e61a09.

📒 Files selected for processing (2)
  • src/runtime/components/Button.vue
  • test/components/Button.spec.ts

Comment thread src/runtime/components/Button.vue
Comment thread src/runtime/components/Button.vue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v4 #4488

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[UButton] is not working with NuxtErrorBoundary

1 participant