ApplicationInsights-JS icon indicating copy to clipboard operation
ApplicationInsights-JS copied to clipboard

[BUG] Promise rejections missing stack trace

Open JohnnyFun opened this issue 4 years ago • 8 comments

Stack trace used to show up in this "details" section from azure insights UI: image

The user was using chrome 92, so shouldn't be a browser issue where it just provides a terrible error.stack value or something.

Let me know if you need any other information. For now, I'll see about adding the error.stack to my custom dimensions area.

And fwiw, that's a custom error that we explicitly throw from a js file: throw new Error('Should not call this with student persona.')

  • OS/Browser: chrome 92
  • SDK Version: 2.7.0
  • How we initialized the SDK:
appInsights = new ApplicationInsights({
    config: {
      instrumentationKey,
      enableUnhandledPromiseRejectionTracking: true,
      // We only want to log errors for debugging.
      disableAjaxTracking: true,
      disableFetchTracking: true,
    },
  })

  appInsights.loadAppInsights()

  appInsights.addTelemetryInitializer(item => {
    const customDimensions = buildCustomDimensions(true)
    const props = (item.baseData.properties = item.baseData.properties || {})
    for (const key in customDimensions) props[key] = customDimensions[key]
    if (isErrorBenign(item.data)) return false // Don't track item
  })

Additional context Might be related to this issue's fix: https://github.com/microsoft/ApplicationInsights-JS/issues/1608. promise rejection stack traces used to show up in the "details" section.

JohnnyFun avatar Sep 23 '21 19:09 JohnnyFun

Hi @JohnnyFun it seems that the image is not attached to your comment, could you please update the image and we can better target the problem? Thanks!

Karlie-777 avatar Sep 23 '21 23:09 Karlie-777

Oh, sorry about that--had copied/pasted my comment on the closed issue I linked to and didn't see I missed the image.

JohnnyFun avatar Sep 24 '21 00:09 JohnnyFun

For now, I'm just tracking the lastStack by calling the following prior to setting up my ApplicationInsights instance and telemetry handler:

let lastStack
...
window.addEventListener('unhandledrejection', e => {
  lastStack = e?.reason?.stack
})

...instantiate app insights and telemetry handler...

And then adding lastStack into my customDimensions in my telemetry handler.

I confirmed that my lastStack is populated for that error, but that app insights telemetry envelope has hasFullStack set to false. So the error goes into app insights code with a stack trace and gets pooped out without one.

Fwiw, app insights seems to retain the rejected promise rejection's stack trace for simple tests like calling this function:

function intentionallyThrowInPromise() {
    new Promise(() => {
      setTimeout(() => {
        throw new Error('CN Dev tools button clicked (Test AppInsights unhandled Promise rejection)')
      }, 100)
    })
  }

But for some reason, it doesn't retain the stack trace for my example case where I throw a new Error from somewhere deeper.

I'll let you know if I notice anything else. Let me know if you need/want any other details of my scenario.

JohnnyFun avatar Sep 28 '21 16:09 JohnnyFun

@JohnnyFun Thanks for the details!

After investigation, the major problem that leads to no error trace might be the way we parse onunhandledrejection. Currently we throw error.reason.toString() to Exception.CreateAutoException() function and the error.reason.toString() will expose no detailed trace stack to Exception.CreateAutoException() . Instead we should use error.reason.stack.toString() to enable full trace tracking.

and please let us know if you notice anything else!

Karlie-777 avatar Sep 29 '21 21:09 Karlie-777

Ah, looks like that CreateAutoException doesn't pass a stack parameter through:

image

So looks like you just need to pass that through with: error.reason?.stack

image

JohnnyFun avatar Sep 29 '21 21:09 JohnnyFun

I'm pretty sure unhandled promise errors always put their exception on reason, so error.reason?.stack should suffice. But might want to double check that you don't need something like error.stack ?? error.reason?.stack.

JohnnyFun avatar Sep 29 '21 21:09 JohnnyFun

Otherwise, yes looks like your strategy would also work since stackDetails null coalesce stack and fall back to error, but if that stack parameter is there and just not being passed, it would seem to me it should be passed? :shrug:

image

JohnnyFun avatar Sep 29 '21 21:09 JohnnyFun

This Issue will be closed in 30 days. Please remove the "Stale" label or comment to avoid closure with no action.

github-actions[bot] avatar Jul 27 '22 07:07 github-actions[bot]

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Aug 27 '23 00:08 github-actions[bot]