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

[Feature request] Show browser error overlay for runtime errors #2076

Open
martinszeltins opened this issue Feb 18, 2021 · 16 comments · May be fixed by #6274
Open

[Feature request] Show browser error overlay for runtime errors #2076

martinszeltins opened this issue Feb 18, 2021 · 16 comments · May be fixed by #6274
Labels
enhancement New feature or request has workaround

Comments

@martinszeltins
Copy link

martinszeltins commented Feb 18, 2021

I really like the browser error overlay that we get for compile errors (server.hmr.overlay). But runtime errors still appear only in console. It would be nice if runtime errors could also be displayed using the nice browser error overlay.

For example, it would be nice to get the overlay if I forgot to import ref:

<script setup>
    import HelloWorld from './components/HelloWorld.vue'

    const name = ref('Martin')
</script>

I'm talking about this overlay:

@yyx990803 yyx990803 added the enhancement New feature or request label Feb 18, 2021
@ygj6
Copy link
Member

ygj6 commented Mar 4, 2021

Sometimes runtime errors occur after most of the page is loaded normally and the page can be used normally. In this case, will the page be replaced with the browser error overlay?

@jugglingcats
Copy link

In React they prevent partial page from being rendered if there is an error, so error overlay is appropriate in all cases. It would be a nice enhancement particularly for new users and is present in CRA, NX, Snowpack etc.

@janwirth
Copy link

janwirth commented May 23, 2021

The overlay is an overlay so it's not replaced, it's overlaid or am I missing something here?

This does the trick for me:

// REGISTER ERROR OVERLAY
const showErrorOverlay = err => {
    // must be within function call because that's when the element is defined for sure.
    const ErrorOverlay = customElements.get('vite-error-overlay')
    // don't open outside vite environment
    if (!ErrorOverlay) {return}
    console.log(err)
    const overlay = new ErrorOverlay(err)
    document.body.appendChild(overlay)
}

window.addEventListener('error', showErrorOverlay)
window.addEventListener('unhandledrejection', ({reason}) => showErrorOverlay(reason))

@andrew-knack
Copy link

andrew-knack commented Sep 3, 2021

@FranzSkuffka Almost but the overlay needs the frame to be defined on the error to get correct formatting.

The code you posted will essentially show

Error: boom
    at http://localhost:3000/src/index.tsx:17:7

vs what I think most people expect

Runtime error at [filepath]
[error message]
/[filepath]:17:0
17 |      throw new Error('boom')
18 |      ^  

at [stacktrace]

On an unrelated note small bug in the code you posted, I think you meant to pass in the error not the event.

window.addEventListener('error', ({error}) => showErrorOverlay(error));

@TechAkayy
Copy link

Please prioritise this one, we are all spoilt by our previous experiences with webpack and other dev-servers. Really hard to live without the run-time overlay. Thanks!

@arbassett arbassett linked a pull request Dec 27, 2021 that will close this issue
9 tasks
@TechAkayy
Copy link

Thanks @arbassett for the related PR (#6274) you are working on. Will this PR cover showing all runtime errors in the overlay? Would be great if it does.

Here is example where prop validations fail (validator fn & type check). At the moment, we are forced to keep the browser console always open to even notice these important errors.

image

@Inviz
Copy link

Inviz commented Jan 18, 2023

I thought i was doing something wrong, but it really is a problem. I would really love to see this improved

@uwaisdev
Copy link

// REGISTER ERROR OVERLAY
const showErrorOverlay = err => {
    // must be within function call because that's when the element is defined for sure.
    const ErrorOverlay = customElements.get('vite-error-overlay')
    // don't open outside vite environment
    if (!ErrorOverlay) {return}
    console.log(err)
    const overlay = new ErrorOverlay(err)
    document.body.appendChild(overlay)
}

window.addEventListener('error', showErrorOverlay)
window.addEventListener('unhandledrejection', ({reason}) => showErrorOverlay(reason))

Fantastic, seems to have solved it for now.

@vKongv
Copy link

vKongv commented Apr 8, 2023

The overlay is an overlay so it's not replaced, it's overlaid or am I missing something here?

This does the trick for me:

// REGISTER ERROR OVERLAY
const showErrorOverlay = err => {
    // must be within function call because that's when the element is defined for sure.
    const ErrorOverlay = customElements.get('vite-error-overlay')
    // don't open outside vite environment
    if (!ErrorOverlay) {return}
    console.log(err)
    const overlay = new ErrorOverlay(err)
    document.body.appendChild(overlay)
}

window.addEventListener('error', showErrorOverlay)
window.addEventListener('unhandledrejection', ({reason}) => showErrorOverlay(reason))

I'm able to make the overlay more usable with information such as stacktrace using window.onerror and pass err object from 5th param. I also check if it's dev env to make sure it doesn't include this code in prod in case causing any side effect

if (import.meta.env.DEV) {
  window.onerror = (event, source, lineno, colno, err) => {
    // must be within function call because that's when the element is defined for sure.
    const ErrorOverlay = customElements.get('vite-error-overlay');
    // don't open outside vite environment
    if (!ErrorOverlay) {
      return;
    }
    const overlay = new ErrorOverlay(err);
    document.body.appendChild(overlay);
  };
}

Example using window.onerror

image

addEventListener('error', ...) only emit the error event which doesn't include stacktrace, see: https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event#syntax

@c10b10
Copy link

c10b10 commented Aug 3, 2023

Where do you precisely add this code @vKongv for it to work?

I've tried adding it in the index.tsx of a React app to make it work. It does work for errors in that file, but fails for any other file.

@krzkaczor
Copy link

@c10b10 you can dump it into <script> tag in your index.html. However I am also wondering what's the best way to avoid bundling this code 🤔

@lxe
Copy link

lxe commented Oct 5, 2023

Not sure if there's a better way to do this at this point, but for ErrorEvents, you also need to pass the error property into ErrorOverlay:

window.addEventListener('error', ({error}) => showErrorOverlay(error)); // here

@Walidoux
Copy link

Walidoux commented Nov 2, 2023

A little hint for those who are using typescript and would like to switch the prop err from any to something more accurate reading their code from hmrPayload.ts, ref: https://github.com/vitejs/vite/blob/main/packages/vite/types/hmrPayload.d.ts#L45

import type { ErrorPayload } from 'vite'

export const showErrorOverlay = (err: Partial<ErrorPayload['err']>) => {
  const ErrorOverlay = customElements.get('vite-error-overlay')
  if (ErrorOverlay == null) return
  document.body.appendChild(new ErrorOverlay(err))
}

@gaurav21r

This comment has been minimized.

@JanderSilva-Acerta
Copy link

Any solution for stack trace showing different lines than actual error position?

@BlueManiac
Copy link

BlueManiac commented Nov 13, 2024

Any solution for stack trace showing different lines than actual error position?

I did some work on this using a vite plugin instead.
Check rewriteStacktrace and generateCodeFrame
in
https://github.com/BlueManiac/DotnetViteVueTemplate/blob/f6996afb8ddda8d56b36042a63cab8a194e91011/src/Web/Util/Plugins/vite-runtime-error-plugin.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request has workaround
Projects
None yet
Development

Successfully merging a pull request may close this issue.