Skip to content

Conversation

@MiniJude
Copy link

@MiniJude MiniJude commented Dec 19, 2025

  • Added logic to manage the connection state between the modal and its parent component.

  • Introduced a flag to track if the modal is connected, ensuring proper handling

    during re-creation and API extension.

  • Enhanced error handling when connecting to the parent modal's API.

Description

This PR fixes a bug in the modal connection handling logic where the __vbenModalConnected flag was set to true before verifying that the parent's extendApi call succeeds. If Object.setPrototypeOf within extendApi throws an error, the flag remains true despite the connection being incomplete. This prevents subsequent child modals from attempting to connect since they check this flag to decide whether to connect.

The Problem:

本地复现代码:
git clone -b "pr-#7035问题复现" --single-branch https://github.com/MiniJude/vue-vben-admin.git

pnpm dev:playground

image
LenovoPcManager_QDKPoDZvFi.mp4
  • The child modal sets injected.__vbenModalConnected = true at line 131 before calling extendApi
  • If extendApi throws an error (e.g., Object.setPrototypeOf fails), the flag remains true
  • Subsequent child modals cannot retry the connection because they check this flag

The Solution:

  • Move the flag setting to after the extendApi call succeeds
  • Wrap the connection logic in a try-catch block
  • Ensure the flag remains false if connection fails, allowing retries

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.

Checklist

ℹ️ Check all checkboxes - this will indicate that you have done everything in accordance with the rules in CONTRIBUTING.

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs:dev command.
  • Run the tests with pnpm test.
  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Summary by CodeRabbit

  • Bug Fixes
    • Fixed modal connection reliability so nested modals correctly recover from parent connection errors.
    • Ensured modal lifecycle behaves consistently whether used standalone or connected to a parent.
    • Improved error handling to allow retries when connecting child modals to parent modals.

✏️ Tip: You can customize this high-level summary in your review settings.

- Added logic to manage the connection state between the modal and its parent component.

- Introduced a flag to track if the modal is connected, ensuring proper handling

  during re-creation and API extension.

- Enhanced error handling when connecting to the parent modal's API.
@changeset-bot
Copy link

changeset-bot bot commented Dec 19, 2025

🦋 Changeset detected

Latest commit: 6c128cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 43 packages
Name Type
@vben-core/popup-ui Patch
@vben/common-ui Patch
@vben/layouts Patch
@vben/web-antd Patch
@vben/web-ele Patch
@vben/web-naive Patch
@vben/web-tdesign Patch
@vben/docs Patch
@vben/playground Patch
@vben-core/design Patch
@vben-core/icons Patch
@vben-core/shared Patch
@vben-core/typings Patch
@vben-core/form-ui Patch
@vben-core/layout-ui Patch
@vben-core/menu-ui Patch
@vben-core/shadcn-ui Patch
@vben-core/tabs-ui Patch
@vben-core/composables Patch
@vben-core/preferences Patch
@vben/node-utils Patch
@vben/tailwind-config Patch
@vben/tsconfig Patch
@vben/vite-config Patch
@vben/commitlint-config Patch
@vben/eslint-config Patch
@vben/prettier-config Patch
@vben/stylelint-config Patch
@vben/constants Patch
@vben/icons Patch
@vben/locales Patch
@vben/preferences Patch
@vben/stores Patch
@vben/styles Patch
@vben/types Patch
@vben/utils Patch
@vben/access Patch
@vben/hooks Patch
@vben/plugins Patch
@vben/request Patch
@vben/backend-mock Patch
@vben/turbo-run Patch
@vben/vsh Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

Walkthrough

Introduces a dedicated injectContext and a __vbenModalConnected flag to manage parent-child modal connections, adds guard logic to decide when to connect to a parent, and wraps parent extendApi calls in try/catch to reset connection state on failure.

Changes

Cohort / File(s) Summary
Modal connection state management
packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts
Create a separate injectContext for modal injection, add __vbenModalConnected flag, move provide-data creation into component scope, make extendApi set the flag on success, have reCreateModal reset it, add shouldConnectToParent guard, and wrap parent extendApi invocation in try/catch to reset flag on error.
Changelog
.changeset/fix-modal-connection-handling.md
Add patch changelog noting fix: only set __vbenModalConnected after successful parent extendApi to avoid blocking retries when prototype-setting errors occur.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to focus on:
    • Correctness of __vbenModalConnected transitions (initial, after successful parent connect, on error, on reCreateModal)
    • Behavior of shouldConnectToParent in all lifecycle paths (new modal, reconnect, nested modals)
    • Proper propagation and mutability of injectContext vs previously provided plain object
    • Error handling path: rethrow semantics and side effects

Possibly related PRs

Suggested reviewers

  • anncwb
  • jinmao88
  • vince292007

Poem

🐰✨ I hopped in code where modals meet,
A tiny flag to keep things neat,
If parent calls succeed, we cheer,
If errors come, we step back, dear —
A safer loop, with carrots sweet 🥕

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing the connection handling logic for external modals, which is the primary focus of the changeset.
Description check ✅ Passed The PR description is comprehensive, detailing the bug, problem explanation with reproduction steps, solution approach, and addressing all required template sections including type of change and checklist.
✨ 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: 1

🧹 Nitpick comments (1)
packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts (1)

79-82: Consider improving type safety.

The injected variable is typed as any, which bypasses TypeScript's type checking. While this may be intentional for flexibility, consider defining an interface for the injection context to improve type safety and IDE support.

🔎 Suggested improvement

Define an interface for the injection context:

interface ModalInjectContext {
  __vbenModalConnected: boolean;
  extendApi?: (api: ExtendedModalApi) => void;
  options?: ModalApiOptions;
  reCreateModal?: () => Promise<void>;
}

Then update line 79:

-  const injected = inject<any>(USER_MODAL_INJECT_KEY, {});
+  const injected = inject<ModalInjectContext>(USER_MODAL_INJECT_KEY, {});
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1479f15 and 8327106.

📒 Files selected for processing (1)
  • packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5397
File: playground/src/bootstrap.ts:23-30
Timestamp: 2025-01-15T04:29:13.944Z
Learning: In the Vue-Vben-Admin project, commented code in bootstrap.ts showing modal and drawer configuration examples should be preserved as reference documentation, even after moving to CSS variables for z-index management.
🧬 Code graph analysis (1)
packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts (1)
packages/@core/ui-kit/popup-ui/src/modal/modal.ts (1)
  • ExtendedModalApi (154-158)
⏰ 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). (2)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: post-update (windows-latest)
🔇 Additional comments (1)
packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts (1)

130-140: Try-catch structure is well-designed.

The connection logic is properly wrapped in a try-catch block that:

  • Sets the connection flag only after extendApi succeeds (line 134)
  • Resets the flag on failure (line 137)
  • Propagates errors to the caller (line 138)

Note: Line 137 is currently necessary because line 40 prematurely sets the flag to true. Once line 40 is removed (as noted in the previous comment), line 137 becomes redundant but serves as defensive coding and can be kept.

Comment on lines +37 to +52
const injectContext: any = {
__vbenModalConnected: false,
extendApi(api: ExtendedModalApi) {
injectContext.__vbenModalConnected = true;
// 不能直接给 reactive 赋值,会丢失响应
// 不能用 Object.assign,会丢失 api 的原型函数
Object.setPrototypeOf(extendedApi, api);
},
options,
async reCreateModal() {
injectContext.__vbenModalConnected = false;
isModalReady.value = false;
await nextTick();
isModalReady.value = true;
},
});
};
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 | 🔴 Critical

Line 40 should be removed to complete the fix.

According to the PR objectives, the fix should "move setting of __vbenModalConnected to after extendApi succeeds." However, line 40 still sets the flag prematurely before Object.setPrototypeOf on line 43 completes. If setPrototypeOf throws, the flag will have been set to true temporarily.

While the catch block on lines 135-139 attempts to handle this by resetting the flag to false, the design is fragile. The correct fix is to remove line 40 entirely and rely solely on line 134 (which sets the flag after the entire extendApi call succeeds).

🔎 Proposed fix
        const injectContext: any = {
          __vbenModalConnected: false,
          extendApi(api: ExtendedModalApi) {
-           injectContext.__vbenModalConnected = true;
            // 不能直接给 reactive 赋值,会丢失响应
            // 不能用 Object.assign,会丢失 api 的原型函数
            Object.setPrototypeOf(extendedApi, api);
          },

This ensures the flag is set only once, at the correct location (line 134), after confirming the entire connection succeeded.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const injectContext: any = {
__vbenModalConnected: false,
extendApi(api: ExtendedModalApi) {
injectContext.__vbenModalConnected = true;
// 不能直接给 reactive 赋值,会丢失响应
// 不能用 Object.assign,会丢失 api 的原型函数
Object.setPrototypeOf(extendedApi, api);
},
options,
async reCreateModal() {
injectContext.__vbenModalConnected = false;
isModalReady.value = false;
await nextTick();
isModalReady.value = true;
},
});
};
const injectContext: any = {
__vbenModalConnected: false,
extendApi(api: ExtendedModalApi) {
// 不能直接给 reactive 赋值,会丢失响应
// 不能用 Object.assign,会丢失 api 的原型函数
Object.setPrototypeOf(extendedApi, api);
},
options,
async reCreateModal() {
injectContext.__vbenModalConnected = false;
isModalReady.value = false;
await nextTick();
isModalReady.value = true;
},
};
🤖 Prompt for AI Agents
In packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts around lines 37 to 52,
remove the premature assignment that sets injectContext.__vbenModalConnected =
true at line 40; the flag should only be set after extendApi completes
successfully (as already done later around line 134), so delete that early set
to avoid transient true state if Object.setPrototypeOf throws and rely on the
existing post-success assignment.

@chenwei1109
Copy link
Contributor

刚刚复现你的问题,但未能复测出你的问题,drawer组件貌似有你说的 问题,Modal我没复测出来

@MiniJude
Copy link
Author

MiniJude commented Dec 22, 2025

https://github.com/MiniJude/vue-vben-admin/tree/pr-%237035%E9%97%AE%E9%A2%98%E5%A4%8D%E7%8E%B0

您好,我复现了,可以clone一下代码本地启动:
git clone -b "pr-#7035问题复现" --single-branch https://github.com/MiniJude/vue-vben-admin.git

pnpm dev:playground

@jinmao88
Copy link
Collaborator

有一个PR 修复了此问题 如果问题已解决 close一下这个pr

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants