vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.86k stars 8.36k forks source link

Error codes in production not passed to error handlers as described #11053

Open roberthand9 opened 6 months ago

roberthand9 commented 6 months ago

Vue version

3.4.27

Link to minimal reproduction

https://play.vuejs.org/#__PROD__eNp9UrFOwzAQ/ZWTl6SiSgaYqlAJqg4wAAJGL1FyTV0c27KdtlKVf+fs0FCq0iHyu3fP8fM9H9iDMdm2QzZjhausMB4c+s7MuRKt0dbDAbRaWqvtojS+s1hDDyurW0hoWzLKFro1P3yWhyL8ldpcnW1PUwzlFIRyvlQVBrTSE7ifw4ErgEorpyVmUjdpcn52kM6AswRuIqYloWrCVU9fkQ93IPdUeGyNLD1SBVAETznBIj/h2ZR5RweuRJNtnFY0huiBs4rkQqJ9NV6QIc5mg7vQK6XUu+fIedvh9MhXa6y+LvAbtw8cZ28WHdotcjb2fGkb9EN7+fGCe8Jjs9V1J0l9pfmONKwueBxkj52qyfaJLrp9iikJ1Xy65d6jcsdLBaNB2Uc9Z5RamNR/V/+1e5vdxX00eZriMfEL78ivrd5BjDFN4gKRUtCic2WDIb1rydViGwFBJ7WHkCLhfOD/5tl/A2U68nY=

Steps to reproduce

Open dev tools when in prod mode on reproduction link, see logged to the console output of 'info' parameter passed to onErrorCaptured hook

What is expected?

From the description at https://vuejs.org/error-reference the string 'setup function' should be mapped to 0

So the number 0 should be passed as the info parameter to the onErrorCaptured hook

What is actually happening?

The string 'https://vuejs.org/error-reference/#runtime-0' is passed as the info parameter

System Info

No response

Any additional comments?

The change was made in this PR https://github.com/vuejs/core/pull/9165 but I can't find any context as to why

edison1105 commented 6 months ago

Is your codebase dependent on error codes? I think this way, users can quickly navigate to the error code page.

Perhaps the documentation needs to be updated to avoid causing confusion for users.

roberthand9 commented 6 months ago

I'm using suspense and allow errors in async child components to bubble to the parent component where they're handled by an onErrorCaptured hook. There's a check to see if the source of the error is a setup function as that's where I would expect any 'expected' errors to be thrown e.g. api request failed - I can then render an error screen based on this and stop the error going any further

Any errors that are not from a setup function are ignored in the hook and left to the default behaviour

In dev this works fine as I can compare the info parameter to 'setup function' but in prod it's the URL described above. I would expect the URL in dev mode in some way but it seems strange to have it in prod

I'm aware suspense is not stable and perhaps I am stretching the use of the onErrorCaptured hook - but it is currently the suggested method https://vuejs.org/guide/built-ins/suspense#error-handling

In any case the docs are incorrect as they are and I don't see why you wouldn't want to pass in the code as it's described

LinusBorg commented 5 months ago

I don't see why you wouldn't want to pass in the code as it's described

Providing not just the code, but an URL to a description of the code is better DX as developers who might have been unaware of that page in the docs which is providing these explanations of error codes can directly jump there instead of wondering what 0 is supposed to mean and where to find out about its meaning.

You could do

- if (info === '0' info === 'setup function')
+ if (info.split('#')[1] === 'runtime-0' info === 'setup function')

...and we could adjust the docs accordingly. Alternatively, we could consider ... adding another argument, providing the plain error code - in dev and prod alike?

onErrorCaptured((error, instance, info, errorCode) => {
  console.log(info) // logs 'setup function' in dev, and the URL in prod
  console.log(errorCode) // logs '0' in both modes.
})

This would be an improvement without needing to revert the current behaviour, which would inadvertently break someone else's code.

roberthand9 commented 5 months ago

The documentation surrounding the onErrorCaptured hook is transparent that the argument is swapped in prod vs dev - but I can appreciate what you're saying

I did consider slicing the URL but it felt like relying on an unstable detail (please ignore my use of suspense for this argument...)

As you've suggested I think adding a further argument would be best - people can rely on errorCode being set in all cases with no differing behaviour