We understand you have a problem and are in a hurry, but please provide us with some info to make it much more likely for your issue to be understood, worked on and resolved quickly.
- Sinon version : 1.17.4
- Environment : Firefox
- Example URL :
- Other libraries you are using: mocha, chai
What did you expect to happen?
I expected my own error to be reported, not an internal Sinon error.
What actually happens
An internal Sinon error is shown.
How to reproduce
Describe _with code_ how to reproduce the faulty behaviour,
or link to code on JSBin or similar
In sinon/lib/sinon/call.js
, this code is giving me the error that this.getStackFrames(...)[0] is undefined
:
if (this.stack) {
callStr += this.getStackFrames()[0].replace(/^\s*(?:at\s+|@)?/, " at ");
}
From the following:
getStackFrames: function () {
// Omit the error message and the two top stack frames in sinon itself:
return this.stack && this.stack.split("\n").slice(3);
},
...it appears that the slice
is returning an empty array.
I'm hoping this may be enough for you to go on without a specific code sample. Thanks!
This is not sufficient. I don't see any code using Sinon's API at all. You just mention the internals of Sinon, but what about the externals? Waht are you trying to achieve? You can reopen this if you add more info that makes it clear what you are trying to achieve, how, and what is not working.
I'm able to reproduce this in Chrome 55.0.2883.95 for Mac with Sinon 1.17.6 (the latest available at http://sinonjs.org/).
Here's a JSBin with a reduced test case: http://jsbin.com/mufotihiwo/edit?js,console,output
Essentially, it seems like when a stub is passed point-free to Promise#then()
, Sinon _thinks_ it should have a stack trace longer than 3 lines, but it doesn't.
I haven't had a chance yet to figure out exactly what causes this.
I believe this is because the callback is invoked directly by the VM, which means there's nothing in the stack. So when Sinon chops off the first 3 lines (starting at spy.invoke()
), there's nothing left. Then the String#replace()
in call.toString
fails because getStackFrames()[0]
is undefined
.
I _think_ a mitigation strategy would be to simply put a defensive check in toString()
that looks something like:
callStr += ( this.getStackFrames()[0] || 'unknown function' ).replace(/^\s*(?:at\s+|@)?/, " at ");
This is perhaps a slightly better version that also works in Node:
let sinon = require('sinon');
function test() {
let stub1 = sinon.stub().returns( Promise.resolve({}) );
let stub2 = sinon.stub();
function run() {
return stub1().then( stub2 );
}
run()
.then( () => sinon.assert.calledTwice( stub2 ) )
.catch( console.log );
}
setTimeout( test, 0 );
Most helpful comment
This is perhaps a slightly better version that also works in Node: