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

Non-Error exception captured with keys: error #391

Closed
2 of 5 tasks
techyrajeev opened this issue Apr 20, 2018 · 44 comments
Closed
2 of 5 tasks

Non-Error exception captured with keys: error #391

techyrajeev opened this issue Apr 20, 2018 · 44 comments
Assignees

Comments

@techyrajeev
Copy link

techyrajeev commented Apr 20, 2018

OS:

  • Windows
  • MacOS
  • Linux

Platform:

  • iOS
  • Android

Output of node -v && npm -v && npm ls --prod --depth=0

v9.7.1
5.7.1

Config:

Sentry.config('https://[email protected]/...', {
....
}).install()
"react": "16.2.0",
"react-native": "0.53.0",
"react-native-sentry": "^0.35.3",

I am getting lots of crashes with this error -

 } else if (isPlainObject(ex)) {
      // If it is plain Object, serialize it manually and extract options
      // This will allow us to group events based on top-level keys
      // which is much better than creating new group when any key/value change
      options = this._getCaptureExceptionOptionsFromPlainObject(options, ex);
      ex = new Error(options.message);
    } else {
      // If none of previous checks were valid, then it means that
      // it's not a plain Object
      // it's not a valid ErrorEvent (one with an error property)
      // it's not an Error
@devladinci
Copy link

👍 Same here

@HazAT
Copy link
Member

HazAT commented Apr 23, 2018

Can you link a Sentry event here please?

@HazAT HazAT self-assigned this Apr 23, 2018
@techyrajeev
Copy link
Author

Attached a screen shot.

@techyrajeev
Copy link
Author

screen shot 2018-04-24 at 9 55 32 am

HazAT added a commit that referenced this issue Apr 24, 2018
HazAT added a commit that referenced this issue Apr 24, 2018
@HazAT
Copy link
Member

HazAT commented Apr 24, 2018

The next release (which is currently building) should fix this.
Stay tuned for 0.36.0.

@glebmachine
Copy link

Still got this error:
Non-Error exception captured with keys: error, headers, message, name, ok…

@spaceemotion
Copy link

Same here; got mine originating from https://github.com/react-native-community/react-native-share/blob/71737360313e35216062036c8a60416dc2aefc80/index.js#L182 and captured it with

try {
  // my code
} catch (e) {
  Sentry.captureException(e);
}

Am I capturing this the wrong way?

@ldgarcia
Copy link

@HazAT Here is a link for a similar error ("Error: Non-Error exception captured with keys: errorCode, errorMessage…"):

https://sentry.io/share/issue/1d9a134305c747f6a134880e134e51d5/

@jackrvaughan
Copy link

jackrvaughan commented Jul 19, 2018

Also still getting this for an angular6 frontend:

Non-Error exception captured with keys: error, headers, message, name, ok…

EDIT: Sorry - didn't realize this was specific to react-native-sentry

@glebmachine
Copy link

This is not specific to react-native, i got this on angular 6 application

@jackrvaughan
Copy link

@glebmachine Yep, agreed - just this issue is in the react-native-sentry repo

@lcortess
Copy link

Hello, I have the same issue with an angular 6 app, my Raven-js version is 3.26.3 and my sentry version 9.0.0

@zaiddabaeen
Copy link

zaiddabaeen commented Aug 8, 2018

Any updates on this? Happening on angular6 with raven-js 3.26.4.

@lilywang711
Copy link

Happening on vue2 with "raven-js": "^3.26.4"

@lilywang711
Copy link

hey,I found the reason in my project,It doesn't matter with the version or framwork.
The correct format to throw the error is throw new Error(err.data.message), not throw new Error(err)
Which means that the error should be a String

After I modified this, this error has never happened again.
hope this helps

@vdespa
Copy link

vdespa commented Aug 27, 2018

@lilywang711 I would like to disagree, the error can be an Error, ErrorEvent or string.
While only setting a string may work for you, it is not a solution for everybody.

@mehulmpt
Copy link

Happens on Reactjs web app too

@studentIvan
Copy link

same here

@benvinegar
Copy link

So, if this has occurred, it means that Sentry/Raven doesn't believe the error is an Error but rather some other object. And we iterate through the keys to give you a clue what we caught instead.

Note that if you're trying to capture a custom Error (e.g. a subclass, whether defined by your code or the framework code), there's a specific way to do this to make sure it also is detectable as an Error. You can verify it works by verifying MyError instanceof Error evaluates to true.

For example, @jackrvaughan wrote:

Non-Error exception captured with keys: error, headers, message, name, ok…

This means that Sentry/Raven encountered a JavaScript object with this shape:

{
  error: { ... /* some genuine error object probably? */ ... },
  headers: { ... /* some sub-object probably? */ },
  message: '???',
  name: '???',
  ...
}

(That doesn't look like an Error proper to me.)

@acevedomiguel-ai
Copy link

acevedomiguel-ai commented Oct 4, 2018

on Node v10.7.0 using "@sentry/node": "^4.0.3" I got this on my code (Custom error)

class AppError extends Error {
    constructor(error) {
        super(error.err_msg);
        this.name = this.constructor.name;
        Error.captureStackTrace(this, this.constructor);
    }
}

then throw

const a =  new AppError({ err_msg: "test d" })
console.log(a instanceof Error) // true
throw a

and I get:

[email protected]:backend in NodeBackend.<anonymous>
errorNon-Error exception captured with keys: name

@acevedomiguel-ai
Copy link

I tried this solution getsentry/sentry-javascript#1260 (comment) but still getting something like:

errorNon-Error exception captured with keys: [object has no keys]

@kamilogorek
Copy link
Contributor

I'm not able to reproduce this issue locally.

Test code:

const Sentry = require("@sentry/node");

Sentry.init({
  dsn: "http://[email protected]/42",
  beforeSend(event) {
    console.log(JSON.stringify(event, null, 2));
    return null;
  }
});

class AppError extends Error {
  constructor(error) {
    super(error.err_msg);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

throw new AppError({ err_msg: "test d" });

I also tried direct captureException instead of a throw

Sentry.captureException(new AppError({ err_msg: "test d" }));

and it worked just fine as well.

Logs:

{
  "exception": {
    "values": [
      {
        "stacktrace": {
          "frames": [// removed to not take too much space]
        },
        "type": "AppError",
        "value": "test d"
      }
    ]
  },
  "message": "AppError: test d",
  "extra": {
    "AppError": {
      "name": "AppError"
    }
  },
  // rest of the event
}

Tested on @sentry/[email protected] (latest) as well as on mentioned @sentry/[email protected].
And node versions 8.11.1, 10.7.0 and 10.11.0 (latest). All tests with the same results.

@dandanbu3
Copy link

happened on vue2.6 with "raven-js 3.27.0"

@richardshergold
Copy link

We're getting these errors in our Ionic application with raven.js 3.26.4

@kamilogorek
Copy link
Contributor

@richardshergold if you're able to reproduce it locally, use

init({
  dsn: 'your_dsn',
  beforeSend(event, hint) {
    console.log(hint.originalException);
    return event;
  }
})

to investigate what's the shape of the error and update it appropriately.

@richardshergold
Copy link

@kamilogorek thanks - I haven't been able to produce locally actually If I added that code in Production though presumably I would see that info in the console breadcrumbs?

@kamilogorek
Copy link
Contributor

kamilogorek commented Oct 19, 2018

I would see that info in the console breadcrumbs?

No, we are excluding logging from our own callbacks, otherwise, it could create an infinite loop.

You can do something like:

Sentry.init({
  dsn: 'your_dsn',
  beforeSend(event, hint) {
    if (event.message.startsWith('Non-Error exception captured') && hint.originalException.error) {
      Sentry.withScope((scope) => {
        scope.setExtra('nonErrorException', true);
        Sentry.captureException(hint.originalException.error);
      });
      return null;
    }
    return event;
  }
})

This'll prevent those errors from being sent to Sentry and will catch originalException.error instead.
You can do any filtering/modifications in beforeSend or even better, an event processor. https://docs.sentry.io/platforms/javascript/#eventprocessors

@Riccardo-Andreatta
Copy link

@kamilogorek I have those TypeScript errors with the above code:

Property 'setExtra' does not exist on type 'typeof import(sentry browser node module path)

And

Property 'error' does not exist on type 'Error'.

Any idea?

@kamilogorek
Copy link
Contributor

kamilogorek commented Nov 13, 2018

@Riccardo-Andreatta yeh, my example had a bug 😅 It should be scope.setExtra, not Sentry.setExtra.
Regarding first error, it's because we assume originalException is an Error object, but in case of this thread, it's a non-standard one (there's no Error.error in the native implementation).

interface ExtendedError extends Error {
  error: Error; // or `any`
}

and then

if (!hint.originalException) return event;

const customError = (hint.originalException as ExtendedError).error;

if (event.message.startsWith('Non-Error exception captured') && customError) {
  Sentry.withScope((scope) => {
    scope.setExtra('nonErrorException', true);
    Sentry.captureException(customError);
  });
  return null;
}

@richardshergold
Copy link

richardshergold commented Nov 24, 2018

@kamilogorek just looking at this again - we are using Raven.js - can these events be filtered out in the same way using Raven i.e with something like the BeforeSend option you provided above?

@kamilogorek
Copy link
Contributor

@richardshergold you can filter them out (there's dataCallback method), but you wont have an access to the original exceptiion in case you'd like to override it.

@richardshergold
Copy link

@kamilogorek ok thank you. Just so I am understanding (I am in the process of deciding whether or not to move from using raven.js to the Cordova plugin and the new SDK - ours is an Ionic app) - why, with Raven, won't I have access to the original exception? (and would this be a good reason to move from raven.js?)

@kamilogorek
Copy link
Contributor

kamilogorek commented Nov 24, 2018

There's no mechanism that passes original instance that was used to create a Sentry event. Only new v4 SDK has this feature. They are called hints https://docs.sentry.io/platforms/javascript/#hints
Yes, it's one of the reasons why some people move to the new version.

@cihati
Copy link

cihati commented Mar 11, 2019

@kamilogorek @HazAT I'm having this issue in react-native-sentry. How can I do the beforeSend trick @kamilogorek suggested? I do not see beforeSend at https://docs.sentry.io/clients/react-native/config/ (even though it's mentioned in JS, https://docs.sentry.io/platforms/javascript/?platform=node#eventprocessors )?

My error is Non-Error exception captured with keys: error, meta, payload, type (when I click on the blue + symbol in below, I only see "")
image

@kamilogorek
Copy link
Contributor

kamilogorek commented Mar 14, 2019

@cihati this is exactly what you should see, as we are trying to provide any usable information that can be used to find out where is the cause :)

In this case, you somewhere do throw obj where obj is the thing from the log above.

react-native-sentry doesn't have beforeSend with the hint, but setDataCallback instead as it's not part of our core sentry-javascript SDK yet.

Sentry.setDataCallback((event) => {
  // you can inspect and override the event here as described in the comments above
  return event;
});

@valgussev
Copy link

Received the following error Non-Error exception captured with keys: message, status

@kamilogorek
Copy link
Contributor

@valerii-cognite then you have throw { message: '', status: '' } somewhere in your code, where the only thing you should throw is error instance

@DataGreed
Copy link

DataGreed commented Sep 6, 2019

Was it fixed after 0.42.0?

I get the same problem on 0.42

My code:

try {
      active = await this.someMethod()
    } catch (error) {
      alert(error.message)
      Sentry.captureException(error)
      this.setState({
        isDongSomething: false
      })
    }

With this code I get Non-Error exception captured with keys: default in Sentry

@kamilogorek
Copy link
Contributor

@DataGreed not sure what's the status of react-native on this issue as I'm not working on it. However, new v1 uses @sentry/browser (this SDK) instead of old raven.js SDK, thus I assume it should be fixed – https://github.com/getsentry/sentry-react-native/releases

@romelgomez
Copy link

For Angular I having the same problem with this code. I find out that returning a new empty error instance produced this error:

@Injectable()
export class SentryErrorHandler implements ErrorHandler {

  constructor() { }

  handleError(error: any) {

    if (environment.production) {
      Sentry.captureException(error.originalError || error);
    }

    return new ErrorHandler();
  }

}

So I fixed with this solution:

@Injectable()
export class SentryErrorHandler implements ErrorHandler {

  constructor() { }

  handleError(error: any) {

    if (environment.production) {
      Sentry.captureException(error.originalError || error);
    } else {
      console.error(error);
    }

  }

}

@hnrchrdl
Copy link

hnrchrdl commented Dec 3, 2020

i found this answer helpful from a related issue.

@himajaM
Copy link

himajaM commented Dec 21, 2020

@romelgomez where to place this solution code in angular 8

@Injectable()
export class SentryErrorHandler implements ErrorHandler {

constructor() { }

handleError(error: any) {

if (environment.production) {
  Sentry.captureException(error.originalError || error);
} else {
  console.error(error);
}

}

}

and one more question is :::

I think it is not necessary to console the error in production environment ...

@romelgomez
Copy link

romelgomez commented Dec 21, 2020

Hi @himajaM , I think, what i can remember is:

e.g: https://sentry.io/for/angular/

Instead of using ErrorHandler class, I passed a new class SentryErrorHandler

@Injectable()
export class SentryErrorHandler implements ErrorHandler {

  constructor() { }

  handleError(error: any) {

    if (environment.production) {
      Sentry.captureException(error.originalError || error);
    } else {
      console.error(error);
    }

  }

}

environment.production will be true in production and then the error will be registed in Sentry, other side (develoment )will be log in the console of developer and not in Sentry, this is for avoid send develoment errors to the Sentry API

@himajaM
Copy link

himajaM commented Dec 22, 2020 via email

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