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

In my Vue app, bugsnag shows incorrectly the error line in vue file the preview #81

Closed
1 task
vedmant opened this issue Jan 18, 2023 · 3 comments
Closed
1 task

Comments

@vedmant
Copy link

vedmant commented Jan 18, 2023

In my Vue app, bugsnag shows incorrectly the error line in vue file the preview.

In this example error is supposed to be in setup() function in the <script> section, instead it's in the section:
Monosnap ReferenceError in web-ordering 🔊 2023-01-18 12-17-39

Steps to reproduce

  1. Setup a Nuxt 3 project
  2. Integrate bugsnag any way
  3. Upload sourcemaps
  4. Trigger error

Environment

  • bugsnag-source-maps version: 2.3.1
  • Uploading for:
    • [*] Browser
    • [*] Node
      • Node version: v16.18.1
    • React Native
      • React Native version:
  • Command that was run:

@johnkiely1
Copy link
Member

Hi @vedmant, would you be able to write into [email protected] and include a link to the error as it appears on your Bugsnag dashboard. If you could also include some snippets of you Bugsnag configuration code and how the error is being triggered it would also be helpful, for us to investigate. Thanks

@johnkiely1 johnkiely1 added the awaiting feedback Awaiting a response from a customer. Will be automatically closed after approximately 2 weeks. label Jan 20, 2023
@vedmant
Copy link
Author

vedmant commented Jan 20, 2023

@johnkiely1 I have following nuxt 3 module for uploading sourcemaps:

import { defineNuxtModule } from '@nuxt/kit'
import { browser, node } from '@bugsnag/source-maps'

export default defineNuxtModule({
  meta: {
    name: 'bugsnag',
  },

  defaults: {},

  setup (options, nuxt) {
    const publicConfig = nuxt.options.runtimeConfig.public
    if (!publicConfig.bugsnagApiKey) {
      return
    }

    if (nuxt.options.dev) {
      return
    }

    nuxt.options.sourcemap = { server: true, client: true }

    nuxt.addHooks({
      'nitro:config': (config) => {
        config.hooks = {
          compiled: async (nitro) => {
            nitro.logger.log('')
            nitro.logger.start('upload of sourcemaps to bugsnag \n')
            const promises = []

            promises.push(
              node.uploadMultiple({
                apiKey: publicConfig.bugsnagApiKey,
                appVersion: publicConfig.appVersion,
                directory: nitro.options.output.serverDir,
                logger: nitro.logger,
                overwrite: true,
                projectRoot: '/',
              }),
            )

            promises.push(
              browser.uploadMultiple({
                apiKey: publicConfig.bugsnagApiKey,
                appVersion: publicConfig.appVersion,
                directory: nitro.options.output.publicDir,
                logger: nitro.logger,
                overwrite: true,
                baseUrl: publicConfig.baseUrl,
              }),
            )

            await Promise.all(promises)

            nitro.logger.log('')
            nitro.logger.success('upload of sourcemaps to bugsnag \n')
          },
        }
      },
    })
  },
})

and following plugin:

import Bugsnag from '@bugsnag/js'
import { defineNuxtPlugin, useRuntimeConfig } from 'nuxt/app'
import { useAuthStore } from '~/stores/auth'

// https://github.com/vuejs/vue-next/blob/d5cce47789db8f37b9f5f8ea6602ea63e3a04b07/packages/runtime-core/src/component.ts#L153-L167
const LifecycleHooks = {
  BEFORE_CREATE: 'bc',
  CREATED: 'c',
  BEFORE_MOUNT: 'bm',
  MOUNTED: 'm',
  BEFORE_UPDATE: 'bu',
  UPDATED: 'u',
  BEFORE_UNMOUNT: 'bum',
  UNMOUNTED: 'um',
  DEACTIVATED: 'da',
  ACTIVATED: 'a',
  RENDER_TRIGGERED: 'rtg',
  RENDER_TRACKED: 'rtc',
  ERROR_CAPTURED: 'ec',
}

// https://github.com/vuejs/vue-next/blob/d5cce47789db8f37b9f5f8ea6602ea63e3a04b07/packages/runtime-core/src/errorHandling.ts#L6-L24
const ErrorCodes = {
  SETUP_FUNCTION: 0,
  RENDER_FUNCTION: 1,
  WATCH_GETTER: 2,
  WATCH_CALLBACK: 3,
  WATCH_CLEANUP: 4,
  NATIVE_EVENT_HANDLER: 5,
  COMPONENT_EVENT_HANDLER: 6,
  VNODE_HOOK: 7,
  DIRECTIVE_HOOK: 8,
  TRANSITION_HOOK: 9,
  APP_ERROR_HANDLER: 10,
  APP_WARN_HANDLER: 11,
  FUNCTION_REF: 12,
  ASYNC_COMPONENT_LOADER: 13,
  SCHEDULER: 14,
}

// https://github.com/vuejs/vue-next/blob/d5cce47789db8f37b9f5f8ea6602ea63e3a04b07/packages/runtime-core/src/errorHandling.ts#L26-L57
const ErrorTypeStrings = {
  [LifecycleHooks.BEFORE_CREATE]: 'beforeCreate hook',
  [LifecycleHooks.CREATED]: 'created hook',
  [LifecycleHooks.BEFORE_MOUNT]: 'beforeMount hook',
  [LifecycleHooks.MOUNTED]: 'mounted hook',
  [LifecycleHooks.BEFORE_UPDATE]: 'beforeUpdate hook',
  [LifecycleHooks.UPDATED]: 'updated',
  [LifecycleHooks.BEFORE_UNMOUNT]: 'beforeUnmount hook',
  [LifecycleHooks.UNMOUNTED]: 'unmounted hook',
  [LifecycleHooks.ACTIVATED]: 'activated hook',
  [LifecycleHooks.DEACTIVATED]: 'deactivated hook',
  [LifecycleHooks.ERROR_CAPTURED]: 'errorCaptured hook',
  [LifecycleHooks.RENDER_TRACKED]: 'renderTracked hook',
  [LifecycleHooks.RENDER_TRIGGERED]: 'renderTriggered hook',
  [ErrorCodes.SETUP_FUNCTION]: 'setup function',
  [ErrorCodes.RENDER_FUNCTION]: 'render function',
  [ErrorCodes.WATCH_GETTER]: 'watcher getter',
  [ErrorCodes.WATCH_CALLBACK]: 'watcher callback',
  [ErrorCodes.WATCH_CLEANUP]: 'watcher cleanup function',
  [ErrorCodes.NATIVE_EVENT_HANDLER]: 'native event handler',
  [ErrorCodes.COMPONENT_EVENT_HANDLER]: 'component event handler',
  [ErrorCodes.VNODE_HOOK]: 'vnode hook',
  [ErrorCodes.DIRECTIVE_HOOK]: 'directive hook',
  [ErrorCodes.TRANSITION_HOOK]: 'transition hook',
  [ErrorCodes.APP_ERROR_HANDLER]: 'app errorHandler',
  [ErrorCodes.APP_WARN_HANDLER]: 'app warnHandler',
  [ErrorCodes.FUNCTION_REF]: 'ref function',
  [ErrorCodes.ASYNC_COMPONENT_LOADER]: 'async component loader',
  [ErrorCodes.SCHEDULER]:
  'scheduler flush. This is likely a Vue internals bug. '
  + 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next',
}

function formatComponentName (vm) {
  if (vm.$parent === null) { return 'App' }
  return (vm.$options && vm.$options.name) ? vm.$options.name : 'Anonymous'
}

let client

export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig().public
  if (!config.bugsnagApiKey) { return }

  const options = {
    notifyReleaseStages: config.bugsnagStages,
    apiKey: config.bugsnagApiKey,
    environment: config.releaseStage,
    appVersion: config.appVersion,
    autoTrackSessions: false,
  }

  options.onError = (event) => {
    event.errors[0].stacktrace = event.errors[0].stacktrace.map((row) => {
      row.file = row.file.replace('file:https://', '')
      return row
    })
    const user = useAuthStore().user
    user && event.setUser(user.sub, user.email, user.name)
  }

  if (!client) { client = Bugsnag.start(options) }

  nuxtApp.vueApp.config.errorHandler = (err, context, info) => {
    if (err?.statusCode === 404) { return }
    const handledState = { severity: 'error', unhandled: true, severityReason: { type: 'unhandledException' } }
    const event = client.Event.create(err, true, handledState, 'vue error handler', 1)

    event.addMetadata('vue', {
      errorInfo: ErrorTypeStrings[info] || info,
      component: context ? formatComponentName(context, true) : undefined,
      props: (context && context.$options) ? context.$options.propsData : undefined,
    })

    client._notify(event)
    console.error(err)
  }

  nuxtApp.vueApp.provide('bugsnag-client', client)

  return {
    provide: {
      bugsnag: client,
    },
  }
})

I trigger example error in mounted() method by calling non existing method bla().

I see also a warning when building:

WARN Sourcemap is likely to be incorrect: a plugin (nuxt:server-treeshake:transfrom) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help

I sent link to errors to email.

@johnkiely1
Copy link
Member

Hey @vedmant, Thanks for the above, theres a couple of outstanding questions on the related email ticket which we are waiting to hear back from you on. To avoid some duplication and confusion I'm going to close this and let's continue the conversation on the email thread.

@johnkiely1 johnkiely1 removed the awaiting feedback Awaiting a response from a customer. Will be automatically closed after approximately 2 weeks. label Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants