rollbar / rollbar.js

Error tracking and logging from Javascript to Rollbar

Home Page:https://docs.rollbar.com/docs/javascript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Message string is overridden if error argument is submitted

krystof-k opened this issue · comments

If I do Rollbar.warning('Something happened', error);, where error is an Exception object, the message is overridden by the message from the exception.

The way Rollbar's grouping algorithm works in the dashboard, it will display the message of the earliest occurrence in that grouping. If the occurrence from Rollbar.warning('Something happened', error); has been grouped with an earlier occurrence like Rollbar.warning(error); the message displayed will be from the earlier occurrence.

Maybe this is what you're seeing?

Nope, I don't think so. The item is fresh new with only one occurrence, named not by the message (first argument), but by the Exception object message. However the message is present in trace.exception.description.

Here is (almost) the full request payload:

{
  "body": {
    "telemetry": [
      
    ], 
    "trace": {
      "frames": [
        {
          "method": "XMLHttpRequest.p.onreadystatechange", 
          "lineno": 1, 
          "colno": 97174, 
          "filename": "http://localhost:8080/js/about.27ee7b0f.js"
        }, 
        {
          "method": "e.exports", 
          "lineno": 1, 
          "colno": 24726, 
          "filename": "http://localhost:8080/js/about.27ee7b0f.js"
        }, 
        {
          "method": "e.exports", 
          "lineno": 1, 
          "colno": 21342, 
          "filename": "http://localhost:8080/js/about.27ee7b0f.js"
        }
      ], 
      "exception": {
        "message": "Request failed with status code 401", 
        "class": "Error", 
        "description": "Invalid credentials 123456"
      }
    }
  }, 
  "endpoint": "api.rollbar.com/api/1/item/", 
  "uuid": "531834d9-976e-4104-c876-a079df39a62c", 
  "language": "javascript", 
  "level": "warning", 
  "timestamp": 1615829001, 
  "request": {
    "url": "http://localhost:8080/nastaveni", 
    "query_string": "", 
    "user_ip": ""
  }, 
  "server": {}, 
  "environment": "development", 
  "framework": "browser-js", 
  "client": {
    "timestamp": 1615829001, 
    "javascript": {
      "screen": {
        "width": 2560, 
        "height": 1440
      }, 
      "plugins": [
        {
          "name": "Chrome PDF Plugin", 
          "description": "Portable Document Format"
        }, 
        {
          "name": "Chrome PDF Viewer", 
          "description": ""
        }, 
        {
          "name": "Native Client", 
          "description": ""
        }
      ], 
      "cookie_enabled": true, 
      "language": "cs", 
      "browser": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36"
    }, 
    "runtime_ms": 5623
  }, 
  "platform": "browser", 
  "context": "", 
  "notifier": {
    "version": "2.21.0", 
    "name": "rollbar-browser-js", 
    "diagnostic": {
      "original_arg_types": [
        "string", 
        "error"
      ], 
      "raw_error": {
        "message": "Request failed with status code 401", 
        "name": "Error", 
        "constructor_name": "Error", 
        "stack": "Error: Request failed with status code 401\n    at e.exports (http://localhost:8080/js/about.27ee7b0f.js:1:21342)\n    at e.exports (http://localhost:8080/js/about.27ee7b0f.js:1:24726)\n    at XMLHttpRequest.p.onreadystatechange (http://localhost:8080/js/about.27ee7b0f.js:1:97174)\n    at XMLHttpRequest.t._rollbar_wrapped.t._rollbar_wrapped (http://localhost:8080/js/chunk-vendors.7e0e8552.js:7:114783)"
      }
    }, 
    "configured_options": {
      "enabled": true, 
      "scrubFields": [
        "token", 
        "x-authSessionId"
      ], 
      "captureUncaught": true, 
      "captureUnhandledRejections": true, 
      "payload": {
        "environment": "development"
      }
    }
  }, 
  "metadata": {}
}

The occurrence data looks correct.

In that case, the message string should be used for the title string of the item and occurrence, and the exception message should be used only for the exception data itself.

const err= new Error('errorOverrideFunc');
Rollbar.warning('message override', err);

produces:
message-override

Hmm, that's not working for me. I'm using Vue.js integration (according to the guide). Can it be related?

Update: I tried your exact example (from console) and that worked. That is really weird.

It shouldn't be related. Once the keys are set correctly in the payload (and in your example they are), the rest is handled in the Rollbar dashboard. Nothing there would be handled differently based on your JS framework.

Older occurrences disappear after a month, but might still affect this logic. That's still the only thing I can think of that might cause this. Testing using an error with a different backtrace so that it is grouped differently could help verify this.

I just tried sending your dummy error example:

const err = new Error('errorOverrideFunc');
this.$rollbar.warning('message override', err);

and logging an actual browser error from an axios request, in this case 401.

In the first case, the override works, in the second it doesn't – both equally created as new items in Rollbar, not grouped with any of the existing occurrences.

However the exception objects look very different – see first:

image

and second:

image

Can't this be the cause?

Also the first item has Error: in the title (#21 Error: message override) whereas the second does not (#22 Request failed with status code 401).

In the payload for the axios error, what does body.exception look like?

Do you mean data.body.trace.exception in request payload to Rollbar?

This is for the first error:

{
  "class": "Error",
  "message": "errorOverrideFunc",
  "description": "message override"
}

This for the axios error:

{
  "class": "Error",
  "message": "Request failed with status code 401",
  "description": "message override actual error"
}

Yes, thank you.

I've been able to verify the root cause here, and have a test that shows what's happening.

Rollbar's grouping algorithms do more than just grouping, and in some cases they overwrite the title. One of the active rules does overwrite the title if the exception message matched the regex: /^Request failed with status code (\\d+)$/. It rewrites it exactly back to "Request failed with status code 401" (or whatever error code was found), making it quite hard to determine this was happening rather than the exception message being preferred over the description string.

In the following test, the first example shows the title will be overwritten without needing an error generated from axios. The second example shows that the grouping algo behavior is avoided just by changing the message string to a non-matching value.

const errorGroupingRule = function() {
  // This error message matches one of the grouping algo rules.
  const err = new Error('Request failed with status code 401');

  // This will have title: Request failed with status code 401
  rollbar.warning('errorGroupingRule message override', err);
}
errorGroupingRule();

const errorGroupingRule2 = function() {
  // This message won't match the grouping rule.
  const err = new Error('Failed with status code 401');

  // This will have title: errorGroupingRule message override
  rollbar.warning('errorGroupingRule message override', err);
}
errorGroupingRule2();

I see. Do you consider this a feature? Because I find this very confusing and honestly see no reason to do that, if I explicitly set the message, I probably want to see it in the interface. The only workaround I can think of is to override the message in the actual exception object, but I find this rather a dirty hack.

In Rollbar settings under Custom Fingerprinting (https://rollbar.com/waltjones/temakki/settings/custom_fingerprinting/), you can set up custom rules. A doc is here. https://docs.rollbar.com/docs/custom-grouping

When a custom rule matches, no further rules are applied, so this can be used to bypass the default rule.

The following rule worked for me.

[
  {
    "condition": {"all": [
      {"path": "language", "eq": "javascript"},
      {"path": "body.trace.exception.class", "eq": "Error"},
      {"path": "body.trace.exception.message", "regex_match": "^Request failed with status code \\d+$"}
    ]},
    "fingerprint": "{{ default_fingerprint }}",
    "title": "{{ body.trace.exception.description }}"
  }
]

I agree with you about using the description field if it's present, and I'll pass the info along.

@waltjones thanks, I was not aware of this feature, I'll try. However I would keep the issue open if you don't mind, I think this behavior should be changed or at least mentioned in the docs as it is rather confusing.

For further follow up on this, please contact Rollbar support (support@rollbar.com or via chat), since this is not a Rollbar.js SDK related issue.