Subscribe on changes!

`renderToString()` swallows errors

avatar
Mar 10th 2023

Vue version

3.2.47

Link to minimal reproduction

https://github.com/brillout/vue-renderToString-bug

Steps to reproduce

See https://github.com/brillout/vue-renderToString-bug#readme.

What is expected?

renderToString() swallows errors occuring in Vue SFC <script>.

Note that renderToString() does log the error (console.error(error)) but it doesn't throw it (throw error).

What is actually happening?

renderToString() should throw the error so that erroneous state can be detected and handled accordingly.

System Info

No response

Any additional comments?

I don't see any workaround.

Checking whether conole.error() was called during renderToString() cannot be used to detect whether an error occured, because renderToString() is async.

See https://github.com/brillout/vite-plugin-ssr/issues/687 – I consider this a critical bug as showing a blank page instead of an error page is a considerable UX degradation.

avatar
Mar 14th 2023

wow !The logError method does not throw an exception error in the production environment, but only prints the error. I think this is done to avoid the exception error throwing and causing the program to stop or crash. Perhaps vue can add an option for the user to determine whether to throw an exception error in the production environment, but it is actually a big change, involving error handling at runtime, and also needs to expand the compiler options (for example, the slot call code is generated by the compiler, not simply modifying the runtime can be achieved)

avatar
Apr 17th 2023

I consider this a critical bug as showing a blank page instead of an error page is a considerable UX degradation.

Just to reiterate that, from the perspective of vite-plugin-ssr users, I think this should labeled as ❗ p4-important bug.

avatar
Apr 18th 2023

Does app.config.errorHandler work for your use case?

I'm not familiar with the internals of vite-plugin-ssr, but when I added the following lines to the createApp function in renderer/app.js, it successfully showed a 500 page for me:

app.config.errorHandler = (err) => {
  pageContext.errorWhileRendering = err
}
avatar
Apr 18th 2023

Are you successful in a production environment? I was troubleshooting and found that errorHandler seems to end up in the logError function, and logError just prints the error and never throws it in production (maybe I'm wrong 🤣) @sodatea

packages/runtime-core/src/errorHandling.ts -- 》logError

avatar
Apr 18th 2023

Indeed, this seems to be a viable workaround.

@baiwusanyu-c This is how I made it work: https://github.com/brillout/vue-renderToString-bug/commit/68c0707d1663a81f25dd335f6d2056cc7cd8fcaa.

avatar
Apr 19th 2023

Now that there's a workaround, I would like to label this issue as "p3: minor bug". This doesn't mean the issue isn't important, but we need first to fix the regressions, the serious bugs violating documented behavior, and those can't be worked around before coming to this one.

A side note: There are a few other issues related to error handling. May be worth considering when deciding what to do so that we have better design and implementation consistency:

avatar
Apr 19th 2023

Makes sense 👍 and thanks for the pointers.

avatar
Oct 10th 2023

I'm having the same problem. I hope there can be an option here to decide whether to throw an error or not.