Giter Site home page Giter Site logo

Overwrites constructor about error-cause HOT 22 CLOSED

es-shims avatar es-shims commented on May 24, 2024
Overwrites constructor

from error-cause.

Comments (22)

conartist6 avatar conartist6 commented on May 24, 2024 1

I'm closing this issue as what I've learned is that the problem in my code has nothing to do with this shim. While it works file to write class extends Error, attempts to transpile that code down to ES5 are futile (though they may appear to work).

from error-cause.

ljharb avatar ljharb commented on May 24, 2024 1

Unless it's a true instance of the native one, then (for anything that's not Error), slot-checking prototype methods will throw.

For example, Map.prototype.get.call(o, k) should work for any o that claims to be a Map or a Map subclass.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

My code boils down to this:

import Error from 'error-cause/Error';

export default class Errawr extends Error {
  constructor(reason, options) {
    super(reason, options);
    
    Error.captureStackTrace(this, this.constructor);
  }
}

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

In essence Error just isn't considering that it might be a superclass. I think the correct code would be:

O.constructor = this instanceof Error ? this.constructor : Error;

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

Hmm or perhaps the check should simply be this instanceof Object. I think being more permissive is probably better in this case.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

@ljharb I'm going to wait for your feedback on this before I write it up.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

Oh right this instanceof Object is a dumb check. It will pass for everything except calling the function without the new keyword.

Maybe I'm not thinking of the problem in general enough terms. The issue isn't anything to do with constructor specifically, it's just that returning a different instance from the constructor destroys the inheritance chain. It'll even screw up instanceof checks down the line.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

I see that it is legal to call Error without the new keyword. In such a case you definitely do need to return a newly created object. But the rest of the time I think the constructor should not return anything and instead InstallErrorCause onto this. So in that case this instanceof Object really is the right check to differentiate between those two cases.

from error-cause.

ljharb avatar ljharb commented on May 24, 2024

instanceof doesn't work across realms; and yes, Error can be called without new.

from error-cause.

ljharb avatar ljharb commented on May 24, 2024

It would be reasonable to check if O.constructor is already the original Error - and only replace it in that case, I suppose?

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

It won't be global.Error though, it will be a subtype constructor.

from error-cause.

ljharb avatar ljharb commented on May 24, 2024

right, i'm saying if it's a subclass, then this.constructor !== OriginalError, and so we wouldn't this.constructor =.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

But I still think the problem is bigger than that -- that you can't return a different object at all if subclasses are to be supported properly. Edit: maybe that's not right...

from error-cause.

ljharb avatar ljharb commented on May 24, 2024

Yes, that's true - I suspect it's not possible to properly support subclasses here though, since i can't use native class syntax.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

Let me play with it a bit. I'm pretty sure it is possible. I'll build some test cases.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

Here is what I'm imagining, but perhaps you will see problems with this that are as yet invisible to me.

var GetIntrinsic = require('get-intrinsic');
var setProto = require('es-abstract/helpers/setProto');

var $Error = GetIntrinsic('%Error%');

var InstallErrorCause = require('../InstallErrorCause');

function Error(message) {
	var options = arguments.length > 1 ? arguments[1] : void 0;
	if (this == null) {
		return new Error(message, options);
	} else {
		$Error.apply(this, arguments);
		InstallErrorCause(this, options);
	}
}

if (setProto) {
	setProto(Error, $Error);
}

Error.prototype = $Error.prototype;

module.exports = Error;

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

Ah right, precisely because it can be called without new the usual apply trick won't work.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

So it seems that essentially the only thing that works moderately well is to create an error object O and then try to copy all its properties onto this, preferably by enumerating property descriptors and copying them over one by one. But this has poor support, and where it is not supported the resulting "error" will be completely useless (it will contain no stack and no message).

While this shim can't do that, I don't see any problem with using that approach in the library I am writing.

from error-cause.

ljharb avatar ljharb commented on May 24, 2024

I agree your library can do something like that.

The main reason I'm not using this in this polyfill is that Errors do, in fact, have internal slots - at the moment, only node exposes that with util.types.isError, but the stacks proposal will add new ways.

from error-cause.

ljharb avatar ljharb commented on May 24, 2024

Also correct - extending builtins is impossible without native/untranspiled class syntax.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

I mean all you have to do to support extension is to create a facade class around the native type. It's not perfect and you lose instanceof, but you gain a lot in return. I've published facades around the common data structures like Map, but so far I've not had cause to use them.

from error-cause.

conartist6 avatar conartist6 commented on May 24, 2024

It's always something.

from error-cause.

Related Issues (5)

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.