Closed jridgewell closed 4 years ago
This was discussed in #14.
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 errors parameter before message. — https://github.com/tc39/proposal-promise-any/issues/14#issuecomment-468094826
Let's make errors
optional? Doesn't hurt much, but it'd let us put the arguments in the correct (least surprising) order.
That was also discussed (and rejected, at least by e.g. me) in #14.
Fwiw I would also find it more surprising to have message
first, precisely because it seems optional and errors
does not.
precisely because it seems optional and errors does not.
Neither seems optional. But if we have to have "optional" things first, then making them both optional lets us use the least surprising ordering.
Neither seems optional.
I don't share this intuition at all. I encounter (new Error()).stack
or throw new RangeError()
, etc, fairly frequently.
lets us use the least surprising ordering
Again, I would find your proposed ordering more surprising. But also, even if this were not the case, all of
errors
being non-optional (as discussed in #14),message
being optional, as with every other error type, andseem like more important principles, and collectively imply the current ordering.
Incidentally, the current ordering also matches other error types (OverconstrainedError, RTCError) in the web platform. (The latter of those at my request, but it's shipping now.)
Currently it's not possible to switch order of arguments for AggregateError
because of current design of AggregateError, so I'm going to close this issue. We can reopen it if and when we'll realize to make errors
an optional argument.
I still think this is ridiculous. If we want errors
to be non-optional, allow it to be the first or second param. It's not uncommon for functions to juggle their parameters, and we're even discussing it in TC39 with Number.range(to)
.
class AggregateError {
constructor(messageOrErrors, errors) {
if (typeof messageOrErrors !== 'string') {
errors = messageOrErrors;
messageOrErrors = '';
}
// ...
}
}
While i think the arg order should be errors, message
, i think functions “juggling” their params is a massive antipattern, and other than substring i don’t know of any examples in 262. In any proposal, I’d be staunchly opposed to doing that.
i think functions “juggling” their params is a massive antipattern
I think you're using it much more than you realize. Just doing a doc search, I can find:
For node, this is extremely common, because the overriding pattern is "callback goes last". If you want optional parameters, they go before that callback. I think this can be an excellent API pattern, and anything else would have felt worse.
(I can find more, but they're the easiest ones to find are always Node ones because they follow this pattern).
other than substring i don’t know of any examples in 262
I don't think we've had the need in 262 yet, so there aren't any. I can't really think of any API that would have been made better by this, until now.
In any proposal, I’d be staunchly opposed to doing that.
As in https://github.com/tc39/proposal-Number.range/issues/18, I think this an extremely reasonable pattern to use.
node’s and express’ patterns were born and largely locked in by 2012, long before that became a widely accepted antipattern. It’s because i use it a lot that i understand why it’s suboptimal.
I don't think we've had the need in 262 yet, so there aren't any. I can't really think of any API that would have been made better by this, until now.
Not that it justifies anything here, but the Function constructors interpret their arguments as a list of parameter names followed by a body (and the Array constructor arguably also juggles for Array(len)
vs. Array(...items)
).
Why is
errors
the first parameter? Shouldn'tmessage
be first?If someone were to switch from a
TypeError
to anAggregateError
, it'd be surprising thatmessage
is now second.As a bonus, if there are multiple errors, it's pleasing that the array can be multiple lines without a trailing message argument. Kinda like how node's
callback
is always last: