stacktracejs / error-stack-parser

Extract meaning from JS Errors
https://www.stacktracejs.com/#!/docs/error-stack-parser
MIT License
456 stars 52 forks source link

Error when passing ErrorStackParser.parse as callback to Array.prototype.map #41

Open tao-cumplido opened 6 years ago

tao-cumplido commented 6 years ago

I have an array of errors which I want to convert with error-stack-parser. What I did was basically this:

errors.map(ErrorStackParser.parse).forEach(console.log)

Expected Behavior

I expected to get an array of StackFrames for each error.

Current Behavior

TypeError: Cannot read property 'parseV8OrIE' of undefined
    at ErrorStackParser$$parse (error-stack-parser.js:31:29)
    at Array.map (<anonymous>)
    at Object.<anonymous> (test.js:17:8)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)

Steps to Reproduce (for bugs)

const ErrorStackParser = require('error-stack-parser');
const errors = [new Error()];
errors.map(ErrorStackParser.parse).forEach(console.log);

This works:

errors.forEach((error) => console.log(ErrorStackParser.parse(error)))

And surprisingly this works too:

errors.map((error) => ErrorStackParser.parse(error)).forEach(console.log)

Your Environment

error-stack-parser 2.0.1 Node.js 8.9.0 Windows 10

tao-cumplido commented 6 years ago

I figured out why it doesn't work, I didn't know that map receives an optional second argument to be used as this so when used like this it works:

errors.map(ErrorStackParser.parse, ErrorStackParser).forEach(console.log)

I think the changes to the code would be minimal to support the use case without passing the thisArg. Something like this:

function ErrorStackParser$$parse(error) {
    // ...
}

// other methods

return {
    parse: ErrorStackParser$$parse
}
fmartin5 commented 6 years ago

I agree with you @tao-cumplido. As far as I understand, ErrorStackParser is meant to be used as a singleton like e.g. the Math object, so I think its methods should be independant of the this binding.

This could also be done using .bind() to ensure the this binding inside parse() always refer to ErrorStackParser:

    // ... 

    parse: function ErrorStackParser$$parse(error) {
        // ... code
    }.bind(ErrorStackParser),

However .bind() is not supported in old environments.