Q: My code extending Error() is not fully successful for lack of the stack trace sometimes (like here). How can I extend Error() and also get the stack trace all the time?
I've used
- What's a good way to extend Error in JavaScript?
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
I've arrived at MyError() at the top of this code:
"use strict"
/**
* MyError (sync) - descends from Error
* @param {string} inMsg - default null. Should be a string containing information about
* the error.
* Note: technique for extending Error from
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
* (below heading "Custom Error Types"), as observed Mon Sep 19, 2016 and Tue Oct 18,
* 2016 (the code example under that heading changed between those dates).
* https://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript,
* as observed Tue Oct 18, 2016. No mention of copyright restrictions noted.
*/
function MyError(inMsg = null) {
this.name = "MyError"
if (Object.prototype.toString.call(inMsg) === "[object String]" && inMsg.length > 0)
{ this.message = inMsg }
else { this.message = "MyError was called without a message." }
const lastPart = new Error().stack.match(/[^\s]+$/)
this.stack = `${ this.name } at ${ lastPart }`
}
MyError.prototype = Object.create(Error.prototype)
MyError.prototype.name = "MyError"
MyError.prototype.message = ""
MyError.prototype.constructor = MyError
MyError.prototype.toString = function() { return `${ this.name }: ${ this.message }` }
/**
* p and p1 - functions that demonstrate a behavior
* @param { number } n - integer
* @throw { LocError } - if n isn't an integer
*/
function p(n) {
if (!Number.isInteger(n)) { throw new MyError(`n must be an integer n=${ n }`) }
// uses MyError()
}
function p1(n) {
if (!Number.isInteger(n)) { throw new Error(`n must be an integer n=${ n }`) }
// uses Error()
}
if (true) {
console.log(p(3))
console.log(p("t"))
}
else {
console.log(p1(3))
console.log(p1("t"))
}
(That code is at https://jsfiddle.net/BaldEagle/9vp0p3pw/, though I haven't figured out how to execute it there.)
My Windows 10 is current. I'm using Node v6.2.0.
At the bottom of the code are two functions. One calls Error(); the other calls MyError(). There's no other difference.
Below them is an if statement that selects which function you observe. With that if statement set to "true" (as shown), you'll see the result of MyError(). I get
if (!Number.isInteger(n)) { throw new MyError(`n must be an integer n=${ n }`) }
^
MyError at (node.js:160:18)
and only that (no stack trace).
With the if statement set to "false", you'll see the result of Error(). I get
if (!Number.isInteger(n)) { throw new Error(`n must be an integer n=${ n }`) }
^
Error: n must be an integer n=t
at p1 (C:\path\file.js:38:36)
followed by 8 or 10 lines of the preferred stack trace.
Q: My code extending Error() is not fully successful for lack of the stack trace sometimes (like here). How can I extend Error() and also get the stack trace all the time?