

Stop Trying to Catch Me - jlongster
http://jlongster.com/Stop-Trying-to-Catch-Me

======
Arnavion
>Not only is this a ton of boilerplate

Bluebird has an overload of catch() that takes in a parameter for the error
class.
[https://github.com/petkaantonov/bluebird/blob/master/API.md#...](https://github.com/petkaantonov/bluebird/blob/master/API.md#catchfunction-
errorclassfunction-predicate-function-handler---promise)

>I don't care about losing the stack (which is inherent in any async work).

Bluebird gives stack traces across async frames.

>but it breaks an important feature of JavaScript debuggers: break on
exception. If you have break on exception enabled, and you make an error
inside getValue, it now pauses on the throw in the above code instead of
inside getValue where you actually made the mistake.

This is true, although for errors thrown explicitly with throw your debugger
will stop at the actual throw site.

The good thing is the original exception's stack is maintained, so you know
when it came from and can set a bp next time.

>It's cool, I just don't understand why everyone is so excited about a simple
syntactic improvement.

The excitement is related to the comparative ES5 code (state machine) that
would be needed to achieve it, not the ES6 code (generators). Everyone knows
that async/await is a simple wrapper around generators - LukeH's original
proposal describes it as such.

Edit: (And of course await is much clearer than a yield and remembering to
wrap the outermost async function in spawn())

~~~
idbehold
Also, you can just use Bluebird's .error() for catching "operational errors":
[https://github.com/petkaantonov/bluebird/blob/master/API.md#...](https://github.com/petkaantonov/bluebird/blob/master/API.md#error-
rejectedhandler----promise)

Where an operational error "represents an error (that) is an explicit promise
rejection as opposed to a thrown error."

------
humanarity
If it's any consolation, I also dislike promises, though I don't know that
much about them. I feel they don't solve the problem they set out to solve,
"callback hell" or cleanly interleaving async and sync code together, and I
don't find their syntax aesthetic. I feel JSONP, message passing and state
machines are cleaner. I'm unsure why many love promises, and was surprised by
the level of what I'm only comfortable describing as "standards fever" over
the emergent promises spec.

I also think arrows are cool.

Ah, that was refreshing. Thanks you for having the courage to buck the
promises trend, which contributed to inspiring me to speak my mind as well! :)

BTW -- your karma is enormous. What's with that?

~~~
joepie91_
Perhaps this clarifies the possibilities of promises a bit?
[https://coderwall.com/p/ehzcuq/concurrency-in-js-is-easy-
wit...](https://coderwall.com/p/ehzcuq/concurrency-in-js-is-easy-with-
promises)

~~~
humanarity
It's a good overview. I'm thinking about it now :)

Examples 3 and 4 are very neat. And they do make sense as a way to have a
pipeline operate on a range of values which may or may not have resolved yet.
They promise consistency regardless of the "readyState" of the resource. And
the syntax could even be shortened with property getters to something like:

pipe.read(x).split.map(upper).join.write(y)

Which is okay.

There's still something I dislike about them. I really just like the pattern
where everything is a separate service, which send messages to each other. You
can have message queues, and all services can operate simultaneously, and
distribute them across wherever, you can hot-swap them, they're totally de-
coupled, parameter formats aren't limited to Node-style callbacks. And each
service can be "programmed" with a state machine, so everything is totally
declarative, and totally expressive. Throw in complex event processing and you
can do anything. I just really like SoA, and think if you're going to bother
trying to create a solution for the "async opportunity" you may as well do the
most awesome one possible.

I think I mostly get what promises do and how they're useful -- I don't get
why I'd use them over just JSONP and callbacks for something where I'm not
trying to create such an epic solution.

Fundamentally tho I think one major reason contributing to my choice to not
use promises is maybe I'm comfortable with the ambiguity of a value that a
value hasn't resolved yet, I don't need to pretend there's something there
when it isn't!! :)

Or maybe I just have "trust issues", and I don't trust promises in general, no
matter what language you say 'em in! :)

Yeah, that's probably a reason contributing, too -- I like SoA because
everything takes care of its own stuff. No need to promise, just do!!

------
bsimpson
The first time I used Promises (and really, the first time I did any serious
work in Node), I prototyped an isomorphic web server:

[https://github.com/appsforartists/ambidex/blob/master/src/Am...](https://github.com/appsforartists/ambidex/blob/master/src/Ambidex.server.js#L300-L305)

In three different places in that file, you'll find a Promise that ends in
".catch(error => console.error(error.stack))`. Before I learned that bit of
boilerplate, I'd spend an hour staring at my screen wondering why things were
silently broken.

It's mindblowing that errors are implicitly suppressed by default with
Promises. console.error ought to be automatically invoked for any error that
makes it to the root scope without a .catch() (just like it is with sync
code).

~~~
ubolonton_
In Python it's possible, with the use of destructors (like in Twisted). I
don't think it's possible in Javascript.

------
ggchappell
> A newbie to JavaScript will write that code, and be totally bewildered when
> nothing happens.

The above statement is applicable to a _huge_ number of situations in JS. I'm
surprised that so little has been done about it.

------
kylec
Agreed. An exception being silently caught and ignored by es6-promise was the
culprit of a bug hunt that took a lot longer than it could have if the
exception had automatically percolated to the console. I know now about the
infinite try-catch of Promise so it won't be as much of an issue, but I think
it would be better if the exception were uncaught (or re-thrown) if there are
no more handlers on the promise chain. (Not sure how the library would know
that though)

~~~
gradstudent
How is this not a bug in your code? It sounds like you are not handling all
your thrown exceptions? Just the "expected" ones?

Why would you do that?

~~~
kylec
Yes, it was a bug. We did have code in place at the top level to catch
unforeseen exceptions, but it didn't occur to us that we needed to do so
inside the promise as well. We fixed the issue, but finding it was a lot
harder than it needed to be because there was no indication of why something
didn't work, only that it didn't.

------
julius
Yep. It is quite annoying. I remember working with some promise-library
(bluebird iirc), which completely replaced error handling, including the stack
traces. I was working with transpiled code, and the browser could always give
me really helpful stack traces, for normal code, because of the .map files.
That libraries stack traces were useless and made debugging frustrating and
time consuming.

~~~
spion
Bluebird should work just fine in conjunction with .map files. At least in
node it definitely does - we've had no problems debugging typescript code and
getting the actual lines in the typescript file via `source-map-support` [1]

[1]: [http://npm.im/source-map-support](http://npm.im/source-map-support)

------
matb33
I ended up removing instances of try catch and also setTimeout 0 (or
equivalent nextTick) in the promise library I use. Those two things caused me
enough grief on several occasions to force my hand and modify the library's
implementation. The setTimeout one especially baffled me... The straw that
broke the camel's back for me was how it broke IndexedDB transactions

------
_greim_
> It's cool, I just don't understand why everyone is so excited about a simple
> syntactic improvement.

async-function-star is a pretty interesting concept that it at least
theoretically makes possible; AKA being able to both yield _and_ await in a
function.

