You need to fiddle with the inner workings of v8
. See: the wiki entry about the JavaScript Stack Trace API.
I've based a little test on some code in a proposed commit and it seems to work. You end up with an absolute path.
// omfg.js
module.exports = omfg
function omfg() {
var caller = getCaller()
console.log(caller.filename)
}
// private
function getCaller() {
var stack = getStack()
// Remove superfluous function calls on stack
stack.shift() // getCaller --> getStack
stack.shift() // omfg --> getCaller
// Return caller's caller
return stack[1].receiver
}
function getStack() {
// Save original Error.prepareStackTrace
var origPrepareStackTrace = Error.prepareStackTrace
// Override with function that just returns `stack`
Error.prepareStackTrace = function (_, stack) {
return stack
}
// Create a new `Error`, which automatically gets `stack`
var err = new Error()
// Evaluate `err.stack`, which calls our new `Error.prepareStackTrace`
var stack = err.stack
// Restore original `Error.prepareStackTrace`
Error.prepareStackTrace = origPrepareStackTrace
// Remove superfluous function call on stack
stack.shift() // getStack --> Error
return stack
}
And a test that includes omfg
module:
#!/usr/bin/env node
// test.js
var omfg = require("./omfg")
omfg()
And you will get on the console the absolute path of test.js
.
EXPLANATION
This is not so much a "node.js" issue as it is a "v8" issue.
See: Stack Trace Collection for Custom Exceptions
Error.captureStackTrace(error, constructorOpt)
adds to the error
parameter a stack
property, which evaluates by default to a String
(by way of FormatStackTrace
). If Error.prepareStackTrace(error, structuredStackTrace)
is a Function
, then it is called instead of FormatStackTrace
.
So, we can override Error.prepareStackTrace
with our own function that will return whatever we want--in this case, just the structuredStackTrace
parameter.
Then, structuredStackTrace[1].receiver
is an object representing the caller.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…