-
Notifications
You must be signed in to change notification settings - Fork 27
Design AggregateError #14
Comments
I think "optional arguments follow mandatory arguments" is a stronger principle than "subclasses should have the same signature as their superclass", especially given the existence of additional optional arguments on all Error subclasses in many implementations, so I am inclined to put the |
I think errors is optional, as is message. |
I might want an AggregateError with no errors simply to communicate that something nonspecific has happened, say. |
I think AggregateError ought to be reserved for cases where you have a finite (if possibly empty) collection of errors to report. That seems to me to be what the name implies. |
Strongly agree. Is there anything we can do, either in the naming or design, to prevent people from abusing AggregateError as an UnknownError? Perhaps we could even throw if there are 0 errors supplied? |
Speaking about iterability, between Promise.any(failingAsyncTasks).catch(aggregateError => [...aggregateError]).map(...); and Promise.any(failingAsyncTasks).catch(({ errors }) => errors).map(...); I'd prefer latter. Though property named |
Looking at https://tc39.github.io/ecma262/#sec-error-message, message is not in fact optional - so there aren’t any ordering constraints except that if error is optional, it must come last. Given that, i think that it should come last regardless of what requirements it has. |
Sorry, I was using "optional" in the colloquial sense, i.e., the constructor still works if you don't pass that parameter. I think that AggregateError should work if and only if the |
i don’t think the ordering mandate applies unless its optional in the “it’s signature lists it in brackets” sense. I see how it might be awkward to do |
/shrug I disagree. I don't think the spec formalism should guide the API design very much, if there's other arguments one way or another. Edit: or rather, I agree that there is not a mandate, in the strict specification sense, but I continue to think "optional arguments follow required ones" is a good rule to follow when designing APIs.
I would expect them to omit it, as they are required to do per spec for |
Are there HTML error types (that inherit from Error) that take "not a message" as the first argument? It'd be interesting to compare. |
(In general, regarding API design, it seems very strange to me when a subclass's constructor signature is not a superset of its parent class's constructor signature, but to be fair i don't design inheritance-based APIs very often) |
I'm not sure what other error types there are - EDIT: RTCError now takes its not-a-message argument first. |
Personally I would expect indexed properties ( |
@Ginden I'd be pretty reluctant to introduce a new array-like, vs just having a property which is actually an array. |
I agree with that; a new iterable is nbd, but a new arraylike isn’t quite as palatable :-) |
So as I understand it, the API should look like this: class AggregateError extends Error {
message: string;
name: string;
constructor(errors: any[], message: string = '') {
super(message);
if (!Array.isArray(errors) || errors.length === 0) throw new TypeError('AggregateError should provide an array of errors');
this.name = 'AggregateError';
this.errors = errors;
}
} |
I'm for usage iterator protocol for |
@chicoxyzzy I'd disagree on a couple of points:
I think it should be basically the thing I put in the OP. Or to be more precise, in spec text, I would say
If we want to make (Edit: switched the creation of the |
Per #14 (comment) I consider this issue to be resolved. @bakkot's suggested spec text made it into the proposal. Closing this issue. |
Out of curiosity, why should |
Also, considering the fact that https://github.com/tc39/proposal-explicit-resource-management also needs |
@rbuckton I don't have a strong reason. I was mostly thinking that it would be more discoverable that way. But if there's any particular reason for it not to be, I'd be fine with that changing. (Are there other error types which have enumerable properties?) |
|
This is likely because Safari and Node add additional members via Set. Most built-in data properties are non-enumerable. |
It feels like |
@szuend, any opinions on whether the |
No strong opinion whether Another question I have though is, since |
It should get a stack trace from the place it’s created, identically as if any other error type was constructed there. |
I'm primarily in favor of It's unfortunate that
.NET's |
Since non-errors can also be thrown, not everything in the errors array will have a stack trace. |
In the Either way, |
Any recommendation to display a different kind of stack trace than all the current ones makes standardizing stack traces that much harder; I’d prefer to recommend that the stack trace ignore the errors array entirely. |
It's worth noting that there's a difference between the JS-exposed |
Almost all of ES-defined properties on builtin objects are non-enumerable, so I think that I can think of another concern:
What should
No. 2 seems most useful. |
I'm fine with switching @Ginden, that code should throw a TypeError, because instances of |
Per today’s TC39 meeting, we have consensus on |
both however are at different stages. I think it’s fine to have the first one to land be the one to add AggregateError. |
This issue seems to be resolved now. Closing it. |
I'd like to say that it would make serializing errors over JSON (HTTP, RPC, IPC, etc) would be easier if send({ message: error.message, ...error }) as special-handling for Is there any practical reason (other than consistency) to make it non-enumberable? |
You'd need special handling anyway if you want to serialize the |
Good point, but it is still simpler: JSON.stringify(error, value => value instanceof Error ? { message: error.message, ...error } : error) |
See this thread.
Personally I would expect the design to be basically
though it isn't totally obvious to me what order the parameters should go in.
We might also want to make it iterable. I lean towards not - if you want to iterate the errors, iterate the
.errors
- but other people might disagree.The text was updated successfully, but these errors were encountered: