Giter Club home page Giter Club logo

Comments (5)

dougwilson avatar dougwilson commented on July 24, 2024

Hi @purpledrgn I'm sorry this is causing issues for you. It's not trying to actually change the global Error object, but it's just trying to use the Node.js API to capture stack traces

etc.

If there is a better way to accomplish getting the stack, I'm all for it. There is a pretty extensive test suite around this module which should help highlight why this is there; it was added to fix exceptions that were being encountered by users. If you're also encountering exceptions from this, I'd love to get it fixed!

If you can provide a reproduction case I can look into, I can surely help to find a workable solution for you if you like, otherwise you can always make a pull request as well.

from nodejs-depd.

purpledrgn avatar purpledrgn commented on July 24, 2024

The safest way to fix it is to actually check if the type of Error is actually what you think it is. If it isn't ignore it and short circuit out with some default. Checking function/property presence and output sanity of said functions is probably the best way to confirm; and you just might get what you need.

The problem with Error.captureStackTrace is that to actually pass the functionality to something that overwrites Error it is not a trivial problem. Easy to get wrong. Easy to forget to do.

The following is probably the only way to actually ensure your code works:

const NativeError = Error;

class Overwrite {
	constructor() {
		this.stack = "\n\n\n"
	}
}

Object.defineProperty(Overwrite, 'prepareStackTrace', {
	set: handle => {
		NativeError.prepareStackTrace = handle;
	},
	get: () => {
		return NativeError.prepareStackTrace;
	}
});

Overwrite.captureStackTrace = NativeError.captureStackTrace;

Object.defineProperty(Overwrite, 'stackTraceLimit', {
	set: value => {
		NativeError.stackTraceLimit = value;
	},
	get: () => {
		return NativeError.stackTraceLimit;
	}
});

////////////////////////////////////////////////////////////////////////////////////

Error = Overwrite;

////////////////////////////////////////////////////////////////////////////////////

function prepareObjectStackTrace(obj, stack) {
	return stack;
}

function getStack () {
	var limit = Error.stackTraceLimit
	var obj = {}
	var prep = Error.prepareStackTrace

	Error.prepareStackTrace = prepareObjectStackTrace
	Error.stackTraceLimit = Math.max(10, limit)

	// capture the stack
	Error.captureStackTrace(obj)

	// slice this function off the top
	var stack = obj.stack.slice(1)

	Error.prepareStackTrace = prep
	Error.stackTraceLimit = limit

	return stack
}

function callSiteLocation (callSite) {
	var file = callSite.getFileName() || '<anonymous>'
	var line = callSite.getLineNumber()
	var colm = callSite.getColumnNumber()

	if (callSite.isEval()) {
		file = callSite.getEvalOrigin() + ', ' + file
	}

	var site = [file, line, colm]

	site.callSite = callSite
	site.name = callSite.getFunctionName()

	return site
}

function a() {
	var stack = getStack()
	var site = callSiteLocation(stack[1])
	return site;
}

function b() {
	return a();
}

console.log(b());

Any implementation that doesn't do the setter/getter hack there will just fail in mystifying ways. How many times have you written Object.defineProperty like that? I'd wager a lot of random implementations will just not do that. Your code there is also heavily leaning on it, so if it doesn't work it will fail.

You linked to nodejs docs, but only 2 of the 3 are listed there. I don't see any mention of Error.prepareStackTrace in there. It's documented in V8, but not in the official nodejs docs. I have no idea if that's intentional or an omission. Either way, given the example above I recommend refactoring it out because implementations will very likely link back to the captureStackTrace function on the native Error object, but they're unlikely to implement the finesse required for this undocumented feature.

from nodejs-depd.

dougwilson avatar dougwilson commented on July 24, 2024

Yea, I can definitely make changes! If you can provide a reproduction case I can look into, I can surely help to find a workable solution for you if you like, otherwise you can always make a pull request as well along with tests added to the test suite.

from nodejs-depd.

purpledrgn avatar purpledrgn commented on July 24, 2024

Simply comment out in the example I gave you the following:

Object.defineProperty(Overwrite, 'prepareStackTrace', {
	set: handle => {
		NativeError.prepareStackTrace = handle;
	},
	get: () => {
		return NativeError.prepareStackTrace;
	}
});

You'll get a perfect reproduction case.

Besides a, b and the Overwrite bits everything is copy-pasted from your code.

Like I said above I think it's fair to expect overwrites to Error to provide captureStackTrace since it's documented in nodejs docs, but prepareStackTrace is just not documented and too rarely used. Your code is the first time I've ever seen it used. You can also comment out the stackTraceLimit one but that doesn't make much of a difference either way.

from nodejs-depd.

dougwilson avatar dougwilson commented on July 24, 2024

Gotcha. I'm not going to support such an environment who is overwriting the global Error if that is what is happening.

from nodejs-depd.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.