vuejs / rfcs

RFCs for substantial changes / feature additions to Vue core
4.85k stars 549 forks source link

Vue SSR app renderToString catch errors/warnings #628

Open TheSynt4x opened 6 months ago

TheSynt4x commented 6 months ago

Hello everyone! I'd like to discuss a feature request for Vue and it's ability to do catch errors and warnings when they occur on the server-side. I've done research on this topic but it doesn't seem to be possible as of the moment to catch warnings/errors with Vue when using renderToString.

Here's an example of my use case:

const Vue = require('vue');
const { renderToString } = require('vue/server-renderer');

async function render(html) {
    const fullTemplate = `
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
        </head>
        <body>
            ${html}
        </body>
        </html>
    ` 

    const app = Vue.createSSRApp({
        data: function () {
            return {
                vars: {
                    hello: 'world',
                }
            }
        },

        template: fullTemplate,
    })

    try {
        return await renderToString(app);
    } catch(e) {
        console.log('in vue render: ' + e);
        throw e;
    }
}

What I've tried so far:

app.config.errorHandler = function (err, vm, info) {
    console.log('in vue error handler: ' + err);
}

app.config.warnHandler = function (msg, vm, trace) {
    console.log('in vue warn handler: ' + msg);
}

The errorHandler and warnHandler seem not to be working as I do not see my custom console logs. I've also tried attaching these same handlers to Vue itself but it seems to complain that these do not even exist on the Vue instance and throws as en error.

I've also tried the errorCaptured and the warningCaptured lifecycle hook and it doesn't seem to work either. The issue as of right now is that all errors that happen with the template will get outputted to the console.

Let's consider this as an example:

render('{{vars.hello}}');

Example above will work just fine as vars.hello is defined and it'll show world as expected.

If we consider the following as an example, is where we will run into some issues:

render('{{vars.hello}} {{vars.test}}');

vars.test is not defined and it will show nothing, but the issue here is that the error/warning is outputted in the console. Is there any way to get the error be shown in the template itself with a setup like this? From what I've researched, it does not seem possible.