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

unhandledrejection disregards the reason, can't get proper stack trace in userTransform #307

Closed
alexilyaev opened this issue Jun 9, 2017 · 4 comments
Assignees
Labels

Comments

@alexilyaev
Copy link

Hi,

Test case:
https://jsfiddle.net/etu4g6qc/5/

I'm having an issue with debugging an unhandledrejection of a Promise that I"m not handling.
I"m currently logging such errors to a logging service, and what I see is [object Object] and
a short stack trace from Bluebird which doesn't help at all.

After hours of debugging every piece of code I could, I found this:
https://github.com/rollbar/rollbar.js/blob/master/dist/rollbar.umd.js#L209

Rollbar.prototype.handleUnhandledRejection = function(reason, promise) {
          ...
	  if (_.isError(reason)) {
	    item = this._createItem([message, reason, context]);
	  } else {
	    item = this._createItem([message, context]);

reason here came from event.detail (rejectionHandler at https://github.com/rollbar/rollbar.js/blob/master/dist/rollbar.umd.js#L2653) and it's just an Object, not an Error instance, so the item that's created disregards reason.

When debugging in a real world test case I saw that reason contained all of the information I needed (the actual object sent from the server as an error response).

Issues:

  • The payload that's passed to transform (from UserTransform) does not contain reason, so I can't log essential details to the logging service.
  • The rejection can be an Object, in which case body.trace.exception.message is [object Object]

Would appreciate your help.

@coryvirok
Copy link
Contributor

Hi @alexilyaev and thank you for the detailed write-up + repro.

Which browser are you using? I tried on Chrome 58 and saw that the payload sent to the Rollbar server included the correct message in body.trace.exception.message. Also, the transform function will be passed the payload after it's been parsed into the format that the Rollbar API expects. Which means that the reason should be used to populate the body.trace.* fields.

I suspect that this is browser-specific and we need to add some code to the unhandled rejection logic to handle typeof reason === 'Object'.

Here's the payload I saw when I ran the repro code:

{
  "access_token": "POST_CLIENT_ITEM_ACCESS_TOKEN",
  "data": {
    "environment": "development",
    "level": "error",
    "endpoint": "api.rollbar.com\/api\/1\/",
    "platform": "browser",
    "framework": "browser-js",
    "language": "javascript",
    "server": {
      
    },
    "notifier": {
      "name": "rollbar-browser-js",
      "version": "2.0.4"
    },
    "request": {
      "url": "https:\/\/fiddle.jshell.net\/_display\/",
      "query_string": "",
      "user_ip": "$remote_ip"
    },
    "client": {
      "runtime_ms": 891,
      "timestamp": 1497041850,
      "javascript": {
        "browser": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/58.0.3029.110 Safari\/537.36",
        "language": "en-US",
        "cookie_enabled": true,
        "screen": {
          "width": 1440,
          "height": 900
        },
        "plugins": [
          {
            "name": "Widevine Content Decryption Module",
            "description": "Enables Widevine licenses for playback of HTML audio\/video content. (version: 1.4.8.970)"
          },
          {
            "name": "Chrome PDF Viewer",
            "description": ""
          },
          {
            "name": "Native Client",
            "description": ""
          },
          {
            "name": "Chrome PDF Viewer",
            "description": "Portable Document Format"
          }
        ]
      }
    },
    "body": {
      "trace": {
        "exception": {
          "class": "Error",
          "message": "Why u no trace?"
        },
        "frames": [
          {
            "filename": "https:\/\/fiddle.jshell.net\/_display\/",
            "lineno": 48,
            "method": "[anonymous]",
            "colno": 14
          }
        ]
      }
    }
  }
}

@coryvirok coryvirok self-assigned this Jun 9, 2017
@coryvirok coryvirok added the bug label Jun 9, 2017
@alexilyaev
Copy link
Author

alexilyaev commented Jun 10, 2017

@coryvirok I"m using Chrome 58/59 as well, my results match yours, I wasn't specific enough on the use case...

  • I"m calling the server and it returns a 500 with some data about the error
  • The client has an API module that handles all requests, if it sees an API error, it rejects with the data it received (not an Error instance)
  • The function that uses that specific API call doesn't handle that reject (that's what I was trying to find and had trouble with)
  • So Rollbar catches unhandled rejection, but the extra data is lost because rollbar expects specific things to build up body.trace

Another repro, with server response:
https://jsfiddle.net/fdzce383/3/

As you can see, I can't tell anything from this, not the message and not a proper trace.
But I do have everything I need in reason, which is not added to payload like with a normal error.

{
  "environment": "development",
  "level": "error",
  "endpoint": "api.rollbar.com/api/1/",
  "platform": "browser",
  "framework": "browser-js",
  "language": "javascript",
  "server": {},
  "notifier": {
    "name": "rollbar-browser-js",
    "version": "2.0.4"
  },
  "request": {
    "url": "https://fiddle.jshell.net/_display/",
    "query_string": "",
    "user_ip": "$remote_ip"
  },
  "client": {
    "runtime_ms": 2988,
    "timestamp": 1497087631,
    "javascript": {
      "browser": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36",
      "language": "en-US",
      "cookie_enabled": true,
      "screen": {
        "width": 1440,
        "height": 900
      },
      "plugins": [
        {
          "name": "Widevine Content Decryption Module",
          "description": "Enables Widevine licenses for playback of HTML audio/video content. (version: 1.4.8.984)"
        },
        {
          "name": "Shockwave Flash",
          "description": "Shockwave Flash 25.0 r0"
        },
        {
          "name": "Chrome PDF Viewer",
          "description": ""
        },
        {
          "name": "Native Client",
          "description": ""
        },
        {
          "name": "Chrome PDF Viewer",
          "description": "Portable Document Format"
        }
      ]
    }
  },
  "body": {
    "trace": {
      "exception": {
        "class": "(unknown)",
        "message": "[object Object]"
      },
      "frames": [
        {
          "filename": "(unknown)",
          "lineno": null,
          "method": "[anonymous]",
          "colno": 0
        }
      ]
    }
  }
}

@coryvirok
Copy link
Contributor

I see. I was able to repro this by changing this line of your jsFiddle:

reject({new Error('Why u no trace?')});

to

reject({some:"object here"});

@rokob can you take a look at this?

@rokob
Copy link
Contributor

rokob commented Jun 14, 2017

This is always how this has been though right?
c.f.

this.options.transform(payload);

The payload that is passed to the transform function only comes from

NotifierPrototype.unhandledRejection = _wrapNotifierFn(function(reason, promise) {
and it should be clear from reading that code that if reason is not an instance of Error then the only part of the reason/promise that ends up in the payload is in the message via
message = reason.message || String(reason);

We can change this to add whatever is passed as reason to create the item which will add it to custom.

@rokob rokob closed this as completed in f33c957 Jun 15, 2017
mudetroit pushed a commit that referenced this issue Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants