Why do errors in Vue router beforeEach throw no exception when running in V8Js?

1.8k Views Asked by At

I have a Laravel / Vue app using SSR so have JavaScript running server side and client side.

I had a bug in my code where I was checking user.id when the user object was null.

If this had been running client side I would have seen the error in the console and easily fixed it.

However because this was running in v8js I got no output at all and was just a case of trial and error to locate and fix the bug. This reminded me of fixing JS errors in IE6 - not something I want to repeat!

I did try the getPendingException() method but this just gave me a warning about it being deprecated.

Note some errors are generated....

Obvious syntax errors are picked up straight away when I run webpack.

Some errors throw a V8JsScriptException:

if(foo.bar) {}

This generates the error:

V8Js::compileString():86354: ReferenceError: foo is not defined

If I wrap foo in a function and then call it:

function test() {
    if(foo.bar) {}
}
test()

No exception is thrown, but the only output returned is:

ReferenceError: foo is not defined 

However this code that is for my Vue router produces no output at all:

import Vue from 'vue'
import Router from 'vue-router'
import routes from './routes'

Vue.use(Router)

export function createRouter () {
    const router = new Router({
        mode: 'history',
        routes: routes
    })

    router.beforeEach(async (to, from, next) => {
        if(foo.bar) {}
        next()
    })

    return router
}

When I run this same code in the browser the console shows:

ReferenceError: foo is not defined

So it seems JS is creating an error - but somehow V8Js is not passing it on.

Why does the undefined error in the Vue router not throw an exception when run in v8js?

1

There are 1 best solutions below

3
wmjasonward On

Use an onError handler on your router: router.onError

And, since your beforeEnter guard is async, you'll need to call next with the error:

export function createRouter () {
    const router = new Router({
        mode: 'history',
        routes: routes
    })

    router.beforeEach(async (to, from, next) => {
      try {
        if(foo.bar) {}
        next()
      } catch (e) {
        next(e)
      } 
    })

    router.onError(err => {
       print('<!-- router error: ' + err.message + ' -->')
    })

    return router
}

For your example, you could use a synchronous guard and do without the try/catch:

router.beforeEach((to, from, next) => {
    if(foo.bar) {}
    next()
})