Filtered Promise#catch

Jordan Harband ljharb at gmail.com
Wed Oct 11 20:06:15 UTC 2017


Here's why catch guards aren't an easy feature: Promise catch mirrors
syntactic catch. Promise .catch will not get any new features that aren't
simultaneously available to syntactic catch - full stop.

OK, now you're adding syntax, great! How do you match types? `instanceof`
is utterly unreliable, because it doesn't work cross-realm, so a number of
us on the committee would block on that.

OK, now you're adding a cross-realm brand-checking mechanism. There's
committee members who would block on that.

OK, maybe now you're adding a generic matching protocol, because what if
you want users to be able to supply more complex guard checks - oh wait,
there's already a proposal for that:
https://github.com/tc39/proposal-pattern-matching



Please do not assume that any given fun idea, given all the edge cases,
constraints, and interoperability requirements, will be "easy" to add.

On Wed, Oct 11, 2017 at 7:52 AM, Christopher Thorn <morphcham at gmail.com>
wrote:

> Inline
>
> > If you're going to distinguish between "ergonomic" and "easy" in the
> context
> > of JavaScript development, you're going to have to define what you think
> the
> > difference is.
>
> The difference is that it seemed like people thought I meant "this is
> easy to implement", but I was talking about the ergonomics of using
> the functions once they're defined. Or trying to, at least :)
>
> > For something that should, imo, be used in almost every case that
> `catch` is
> > used, I don't think that it just being ergonomic to create your own
> helper
> > functions is enough. Are you going to create your own helper function
> like
> > that for every error type across every file?
>
> In the codebase I am currently working on, I have functions like these
> defined in modules, which I import where they are needed.
>
> > Do you want the developer to provide their own `guard` etc helper
> functions
> > like you did? Why should they have to?
>
> They could be defined by a library, but they don't need to be methods
> the Promise prototype.
>
> I prefer separate functions because of their explicit intent. In
> particular, I'm not a huge fan of bluebird's overloaded `catch`
> method. However, if you don't overload it, it seems like you'd need to
> specify three methods in addition to catch: `catchInstancesOf`, one
> for function predicates, and one for object predicates (I'm not sure
> what I'd call those two). Having four methods for handling rejections
> is too many.
>
> Maybe functions like the ones I demonstrated could be added to the
> standard library (say, as static properties of the Promise object).
>
> Regards,
> Chris
>
> On Wed, Oct 11, 2017 at 7:14 AM, Peter Jaszkowiak <p.jaszkow at gmail.com>
> wrote:
> > If you're going to distinguish between "ergonomic" and "easy" in the
> context
> > of JavaScript development, you're going to have to define what you think
> the
> > difference is.
> >
> > For something that should, imo, be used in almost every case that
> `catch` is
> > used, I don't think that it just being ergonomic to create your own
> helper
> > functions is enough. Are you going to create your own helper function
> like
> > that for every error type across every file?
> >
> > Do you want the developer to provide their own `guard` etc helper
> functions
> > like you did? Why should they have to?
> >
> > As I said before, I think the criticism of overloading is fine. However,
> > this is something more useful than `Array#includes` and already in use
> more
> > often than that Array method.
> >
> > We can use different method names to separate different types of guards
> if
> > you feel like it's a preferable idea. However, it definitely needs to be
> > done because there is significant demand demonstrated by many people
> still
> > using bluebird for these utility functions.
> >
> > On Oct 11, 2017 7:06 AM, "Christopher Thorn" <morphcham at gmail.com>
> wrote:
> >>
> >> I don't think it's pedantic to point out that you're misstating my
> >> argument. I didn't say "easy", I said "ergonomic", after all.
> >>
> >> I've used bluebird quite a lot, and I've also used native promises and
> >> other promise libraries without filtered catch. At first, I missed
> >> this feature from bluebird, but I no longer do.
> >>
> >> Personally, I prefer the ergonomics of helper functions like I
> >> demonstrated to an overloaded `catch` method, especially one which
> >> does different things depending on the types of the arguments that are
> >> passed (one behavior for the instanceof check, another for a function
> >> predicate and another for an object predicate). Using an separate
> >> function gives the user a chance to specify exactly the behavior they
> >> want, no more and no less, and gives the user a chance to name the
> >> filter.
> >>
> >> Regards,
> >> Chris
> >>
> >> On Wed, Oct 11, 2017 at 5:28 AM, Michał Wadas <michalwadas at gmail.com>
> >> wrote:
> >> > I don't get why argument "it's easy to implement in user land" is
> >> > raised.
> >> >
> >> > All Array methods are easy to implement in user land. Including recent
> >> > additions like .includes and ES2015 methods.
> >> >
> >> > Promises are easy to implement in user land. Smallest implementation
> is
> >> > less
> >> > than 1kB AFAIR.
> >> >
> >> > Maps, Sets, WeakSets are trivial to implement in user land if WeakMap
> is
> >> > present. Probably less than 50 lines of code.
> >> >
> >> > Object.values, Object.entries, Object.assign,
> >> > Object.getOwnPropertyDescriptors, Object.is, Array.from, Array.of.
> These
> >> > methods were added recently but they can be implemented in user land.
> >> >
> >> > On 11 Oct 2017 2:28 am, "Christopher Thorn" <morphcham at gmail.com>
> wrote:
> >> >>
> >> >> I agree that catch guards are useful, but they can be implemented in
> >> >> userland fairly ergonomically:
> >> >>
> >> >> ```
> >> >> function guard(predicate, callback) {
> >> >>   return function guarded(reason) {
> >> >>     if (!predicate(reason)) {
> >> >>       throw reason;
> >> >>     }
> >> >>     return callback(reason);
> >> >>   };
> >> >> }
> >> >>
> >> >> function instanceOf(constructor, callback) {
> >> >>   return guard(reason => reason instanceof constructor, callback);
> >> >> }
> >> >>
> >> >> Promise.resolve('invalid')
> >> >>   .then(JSON.parse)
> >> >>   .catch(instanceOf(SyntaxError, reason => {
> >> >>     // do something to handle the syntax error, or perhaps just
> silence
> >> >> it
> >> >>   }));
> >> >> ```
> >> >>
> >> >> Regards, Chris
> >> >> _______________________________________________
> >> >> es-discuss mailing list
> >> >> es-discuss at mozilla.org
> >> >> https://mail.mozilla.org/listinfo/es-discuss
> >> _______________________________________________
> >> es-discuss mailing list
> >> es-discuss at mozilla.org
> >> https://mail.mozilla.org/listinfo/es-discuss
> >
> >
> > _______________________________________________
> > es-discuss mailing list
> > es-discuss at mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
> >
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20171011/8caca910/attachment-0001.html>


More information about the es-discuss mailing list