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

DOMError is captured as [object DOMError] #939

Closed
paularmstrong opened this issue Apr 25, 2017 · 10 comments
Closed

DOMError is captured as [object DOMError] #939

paularmstrong opened this issue Apr 25, 2017 · 10 comments

Comments

@paularmstrong
Copy link

Do you want to request a feature or report a bug?
bug

What is the current behavior?

When a DOMError is thrown, raven-js logs the error as '[object DOMError]' without any proper messaging. reference: https://github.com/getsentry/raven-js/blob/b8afab1d156467cb2cca0a166385fe9a94aff2cb/dist/raven.js#L413

What is the expected behavior?

The DOMError interface is not actually an instance of Error or an Exception and does not include a stacktrace. Since it doesn't pass the isError check, it's converted to a string and is re-thrown.

Our expected behavior would be to pull out the name property and throw/log as DOMError: ${error.name}, so we can have as much context on the error as possible.

Which versions of Raven.js, and which browser and OS are affected by this issue?
Pretty much every version of both.

Did this work in previous versions of Raven.js?
No

Are you using the CDN (http://ravenjs.com)?
No

Are you using hosted Sentry or on-premises?
Hosted

@LewisJEllis
Copy link
Contributor

LewisJEllis commented Apr 25, 2017

This is sort of related to #879 - there are a couple situations where we're relying on Object.prototype.toString and either

We resolved this in raven-node by using node's util.inspect, but would need to add an implementation of something similar to raven-js to use the same strategy.

The other possibility for this case in particular is that we should make isError return true when passed a DOMError, but I don't personally understand everything about what makes a DOMError special or what the resulting captureException behavior would be.

@LewisJEllis
Copy link
Contributor

LewisJEllis commented Apr 26, 2017

So I did some digging on this and I think what we should do is:

  • Not worry about tackling the bigger picture Console instrumentation breaks on objects without prototype #879/util.inspect problem here; out-of-the-box util.inspect impls are too big and it's not pressing enough to take on making a thinner/stripped down alternative
  • Stop special-casing DOMException to pass isError like we started doing in Support DOMexception #919 😕
  • Have some special logic in captureMessage for doing a nicer string formatting of DOMException/DOMErrors along the lines of what you suggested

Regardless of what we actually do, we should try to treat DOMError and DOMException the same way (see "Remarks"), which we're not currently doing. This is sort of tricky because a DOMException is instanceof Error in Chrome, Firefox, Safari but not in Edge or IE. Also, '' + (new DOMException('hi')) gives us "Error: hi" whereas '' + (new DOMError('hi')) just gives "[object DOMError]" as you've observed; we can construct "DOMException: hi" and "DOMError: hi" instead.

Note that we don't re-throw when failing the isError check, we just hand it off to captureMessage where we'll make a synthetic stack trace. If we instead made DOMErrors pass isError, we won't get a stack trace at all (which is currently the case for DOMException).

So right now, DOMExceptions get a reasonable message but no stack, and DOMErrors get a reasonable stack but no message. We can make both get both.

/cc @graingert - considering reverting #919 because we actually don't get a stack trace for DOMExceptions right now, but we would make a synthetic trace if a DOMException failed isError. Curious if you have thoughts and what your initial motivation was for that PR.

Alternative path is to make DOMErrors also pass isError and try to go from there.

/cc @benvinegar

@LewisJEllis
Copy link
Contributor

Realized this also relates to #360.

@benvinegar
Copy link
Contributor

@LewisJEllis I'm okay with special casing DOMException and DOMError rather than, say, JSON-ifying all non-Error-Error objects.

@StudioMaX
Copy link

Bump. I get a lot of reports about this error, which occurs only in Safari (iOS/OSX).

@kamilogorek
Copy link
Contributor

@StudioMaX are you by any chance able to isolate and provide a snippet that I could use to reproduce this issue? It's be very helpful here.

@StudioMaX
Copy link

@kamilogorek unfortunately, I cannot reproduce the error that occurs in my case. I tried partially to implement this commit https://github.com/getsentry/raven-js/pull/1181/files#diff-a4cb6d8063a6aea4bba2d6f10472b5f4R461 on my project for debugging, but when someone throws this error, JSON.stringify() for [object DOMError] says that this object is empty (json {}).

  captureMessage: function(msg, options) {
      // Convert the message into a string
      var exceptionMessage;
      if (typeof msg === 'object' && msg !== null) {
          exceptionMessage = '' + msg + ': ' + JSON.stringify(msg); // <--
      } else {
          exceptionMessage = '' + msg;
      }
   // ...

    var data = objectMerge(
      {
        message: exceptionMessage
      },
      options
    );

Stacktrace here: https://sentry.io/share/issue/602b3ae3524a4450a80033bfb4b437c6/

@kamilogorek
Copy link
Contributor

Addressed in #1310
Will publish patched version by the end of the week.

@kamilogorek
Copy link
Contributor

Released as 3.25.0

@paularmstrong
Copy link
Author

Thanks @kamilogorek!

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

5 participants