Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

if computed returns a object {} and await in setup, triggering the watch callback and causing an infinite loop. #11078

Open
green-mike opened this issue Jun 6, 2024 · 5 comments

Comments

@green-mike
Copy link

green-mike commented Jun 6, 2024

Vue version

3.4.27

Link to minimal reproduction

https://stackblitz.com/edit/nuxt-issues-27454?file=src%2FApp.vue&terminal=dev

Steps to reproduce

  • a computed variable that return an object
  • await something
  • watch the computed variable and set 'immediate' to true

What is expected?

if the computed variable's value changes, trigger the watch context.

What is actually happening?

A recursion occurs and show message 'UnhandledPromiseRejection' in node.

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Maximum recursive updates exceeded. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

System Info

System:
    OS: macOS 14.4.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 121.70 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node
    npm: 10.1.0 - ~/.nvm/versions/node/v20.9.0/bin/npm
    pnpm: 9.1.2 - /opt/homebrew/bin/pnpm
  Browsers:
    Brave Browser: 124.1.65.126
    Chrome: 125.0.6422.142
    Edge: 125.0.2535.85
    Safari: 17.4.1

Any additional comments?

This code causes recursive updates because the computed property routeVariables returns a new object {} each time it is accessed. When mockAsync is awaited, the watch callback is triggered, leading to an infinite loop.
Reporting this bug because the documentation does not indicate that computed values cannot be used in the setup or watch immediate contexts. Moreover, no error messages appear in the client side. I suspect Vue-SSR might be causing this issue. My actual use case is more complex, requiring URL parsing, then calling an API, and setting the return value as the initial value. Therefore, it took considerable time to narrow down and reproduce the issue. During this period, I found that using the oldValue of a computed property to avoid object updates or using newValue in watch can mitigate the problem. However, since there are no errors in the client side and no hints in the documentation, this is still a valuable case to report.

@green-mike
Copy link
Author

Hi, I use boundary in the Vue SFC Playground too, but it still shows 'SSR Error'. I also put it on StackBlitz, and it has the same problem.

@yangliguo7
Copy link
Contributor

Vue SFC Playground

u use ssr option

image

@green-mike
Copy link
Author

Yes, I noticed that this issue only occurs in the SSR environment. The same code does not produce errors in the browser, so I consider it a bug.

@edison1105
Copy link
Member

The issue can no longer be reproduced using the latest version of Vue.
see https://stackblitz.com/edit/nuxt-issues-27454-6qv6vm?file=package.json

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

No branches or pull requests

3 participants