@@ -3066,8 +3066,10 @@ describe('Raven (public API)', function() {
30663066 var error = new ErrorEvent ( 'pickleRick' , { error : new Error ( 'pickleRick' ) } ) ;
30673067 this . sinon . stub ( Raven , 'isSetup' ) . returns ( true ) ;
30683068 this . sinon . stub ( Raven , '_handleStackInfo' ) ;
3069+ this . sinon . spy ( Raven , '_getCaptureExceptionOptionsFromPlainObject' ) ;
30693070 Raven . captureException ( error , { foo : 'bar' } ) ;
30703071 assert . isTrue ( Raven . _handleStackInfo . calledOnce ) ;
3072+ assert . isFalse ( Raven . _getCaptureExceptionOptionsFromPlainObject . called ) ;
30713073 } ) ;
30723074
30733075 it ( 'should send ErrorEvents without Errors as messages' , function ( ) {
@@ -3079,6 +3081,44 @@ describe('Raven (public API)', function() {
30793081 } ) ;
30803082 }
30813083
3084+ it ( "should treat Schrodinger's Error in the same way as regular Error" , function ( ) {
3085+ // Schrodinger's Error is an object that is and is not an Error at the same time
3086+ // Like... error, but not really.
3087+ // But error.
3088+ //
3089+ // To be more exact, it's an object literal or an instance of constructor function
3090+ // that has it's prototype set to the Error object itself.
3091+ // When using `isPlanObject`, which makes a call to `Object.prototype.toString`,
3092+ // it returns `[object Object]`, because any instance created with `new X`
3093+ // where X is a custom constructor like `function X () {}`, it's return value
3094+ // is an object literal.
3095+ // However, because it has it's prototype set to an Error object,
3096+ // when using `instanceof Error` check, it returns `true`, because calls
3097+ // like this, are always going up the prototype chain and will verify
3098+ // all possible constructors. For example:
3099+ //
3100+ // class Foo extends Bar {}
3101+ // class Bar extends Error {}
3102+ //
3103+ // var foo = new Foo();
3104+ //
3105+ // and now `foo` is instance of every "extension" ever created in the chain
3106+ //
3107+ // foo instanceof Foo; // true
3108+ // foo instanceof Bar; // true (because Foo extends Bar)
3109+ // foo instanceof Error; // true (because Foo extends Bar that extends Error)
3110+
3111+ function SchrodingersError ( ) { }
3112+ SchrodingersError . prototype = new Error ( "Schrödinger's cat was here" ) ;
3113+ var error = new SchrodingersError ( ) ;
3114+ this . sinon . stub ( Raven , 'isSetup' ) . returns ( true ) ;
3115+ this . sinon . stub ( Raven , '_handleStackInfo' ) ;
3116+ this . sinon . spy ( Raven , '_getCaptureExceptionOptionsFromPlainObject' ) ;
3117+ Raven . captureException ( error , { foo : 'bar' } ) ;
3118+ assert . isTrue ( Raven . _handleStackInfo . calledOnce ) ;
3119+ assert . isFalse ( Raven . _getCaptureExceptionOptionsFromPlainObject . called ) ;
3120+ } ) ;
3121+
30823122 it ( 'should call handleStackInfo' , function ( ) {
30833123 var error = new Error ( 'pickleRick' ) ;
30843124 this . sinon . stub ( Raven , 'isSetup' ) . returns ( true ) ;
0 commit comments