News for hackers. Stuff that matters.
Re:Node v6.9.0 (LTS) by dcgudeman on Tuesday October 18, 2016 @02:39PM (#12737382)
When a native Promise incurs a rejection but there is no handler to receive it, a warning will be printed to standard error.

Probably the most important change other than improvements in es2015 support.

Re:Node v6.9.0 (LTS) by nilliams on Tuesday October 18, 2016 @03:03PM (#12737621)
Yes, this footgun is why I've been really wary of the of the `fetch()` plus es6-promise polyfill bandwagon. I've been giving that a wide berth. Examples why:

- http://requirebin.com/?gist=8f13d5147c1c252ab1691115bfa8b7c5

- http://requirebin.com/?gist=06e8c85fcaca56c9651c6aabd0d91476

Re:Node v6.9.0 (LTS) by tracker1 on Tuesday October 18, 2016 @03:09PM (#12737676)
how is that any different than any other ignoring of potential errors...

    fs.saveFile(file, function(err){});
I'd spent most of the last month dealing with a codebase that ignored potential errors systematically... which was a HUGE problem when you WANT to throw an error down that hole... "turtles all the way down" and they're eating all the errors.

It's not limited to Promises, or even unique.

Re:Node v6.9.0 (LTS) by nilliams on Tuesday October 18, 2016 @03:18PM (#12737766)
Because it's not just an 'ignoring of errors', it's the fact all exceptions (as in actual errors from the runtime) are silently swallowed. In your example, if you typo in that function body, an exception will be thrown, your program will exit and you will see the stacktrace.

  var fs = require('fs');

  fs.writeFile('foo.data', function(err){
      // A typo here will lead to an exit and stacktrace
      sadsad
  });
Whereas in the Promise examples it is quite literally silently swallowing ALL exceptions thrown, including typos etc.

It is limited to Promises, because they're supposed to help us deal with error propagation, and pass exceptions through to `.catch()` handlers. But if that catch handler is missing, crickets, even for outright invalid code. That doesn't happen with any other construct in JS afaik.

Re:Node v6.9.0 (LTS) by WorldMaker on Tuesday October 18, 2016 @03:35PM (#12737918)
In that example the same error gets thrown with a Promise because you're talking about mostly a JIT error at file load time. (Promise.resolve().then(() => I am a syntax error))

The parent's point is that you still aren't doing anything with the callback errors (that first parameter to most node-style callbacks) and those silent swallows are a lot harder to deal with than Promise's silent swallows because node callback error handling is a convention that is easily missed/forgotten/ignored, whereas Promises always "bubble" exceptions "down the chain" and fixing global unhandled exception handlers in Promises is a lot easier (and done at a platform level) than fixing a codebase full of bad node-style callbacks.

Re:Node v6.9.0 (LTS) by nilliams on Tuesday October 18, 2016 @03:42PM (#12737969)
I disagree. A developer choosing to not handle the 'error' param in an error-first callback at all is incompetence from a node dev, akin to writing 'try-except-pass' in Python, whereas silent swallowing of runtime exceptions is a bug of the runtime and inexcusable.

Btw, I prefer Promises and the error-bubbling approach in principle for the reasons you're getting at, but the current implementations (especially in p0lyfills like es6-promise) are simply broken, due to the standards themselves being lacking. See this comment for fact the fix has been in draft for a while now: https://github.com/stefanpenner/es6-promise/issues/70#issuec...

Re:Node v6.9.0 (LTS) by WorldMaker on Tuesday October 18, 2016 @03:55PM (#12738080)
I disagree. Developers are human and if they have to remember to write extra code to get a thing to do the right thing, they are likely to forget. (try-except-pass is an explicit opt out; if (err) throw err is a "required" opt in.)

This "bug" in some of the Promise runtimes could just as easily be handled by forcing every Promise chain to end in a .catch((err) => /* ... */). Requiring even this little bit is less onerous than node-style callbacks where every "link in the chain" needs explicit opt-in, with Promises you only "have to" opt in and deal with boundaries, just like try-catch in most languages.

Yes, it's not great that Node and some of the browsers initially "missed" the "great try/catch in the sky" catch all logging, but again that is easily resolved at the runtime platform level whereas node can't possibly tell you if a developer missed an if (err) throw err somewhere in a callback chain 10-levels deep and across three or four dependencies.

Re:Node v6.9.0 (LTS) by nilliams on Tuesday October 18, 2016 @04:08PM (#12738181)
I agree that handling promises should be by default better than remembering to 'if (err) throw err' but my original comment was about how spec-adhering promise polyfills like es6-promise are basically broken because they silently swallow the most egregious errors.

They silently swallow all runtime exceptions, not 'error from reading said file you told me to read, that there should, by any sane degree be SOME KIND of error handling for, and for anyone serious about programming in a dynamic language, also test coverage for'.

Those two things are different issues, on different levels.

> Yes, it's not great that Node and some of the browsers initially "missed" the "great try/catch in the sky" catch all logging, but again that is easily resolved at the runtime platform level

That's all my original comment said. The platforms (actually the spec) failed to get it right initially, the implementation was broken and now it is fixed.

Re:Node v6.9.0 (LTS) by dkoston on Tuesday October 18, 2016 @05:57PM (#12739100)
Seriously? It takes 5 seconds to add an eslint rule to avoid this issue.

http://eslint.org/docs/rules/handle-callback-err

Re:Node v6.9.0 (LTS) by WorldMaker on Wednesday October 19, 2016 @10:35AM (#12744133)
The time this bit me the most the error was swallowed in a dependency of a dependency of a gulp plugin. Do you also eslint node_modules//*.js?
Re:Node v6.9.0 (LTS) by minitech on Tuesday October 18, 2016 @08:15PM (#12739880)
In my experience, it has too many false positives to turn on.
Re:Node v6.9.0 (LTS) by dkoston on Wednesday October 19, 2016 @09:29AM (#12743561)
Sorry to hear about your experience. Been using it for years as part of our build processes with no false positives.

You're always welcome to write a replacement if you find it unsuitable.

Re:Node v6.9.0 (LTS) by minitech on Wednesday October 19, 2016 @04:18PM (#12747328)
I don’t need a replacement, just offering an explanation for why some people’s needs might not be satisfied by this rule.
Re:Node v6.9.0 (LTS) by femto113 on Wednesday October 19, 2016 @04:41AM (#12742129)
In some scenarios, particularly when writing scripts, error handling boilerplate code tends to obscure the nominal flow, which can make the script overall harder to debug and thus net more likely to have errors.

Coincidentally I was annoyed by this very fact a few years ago so I developed https://www.npmjs.com/package/callback-wrappers which made the boilerplate for common error handling scenarios (logging, throwing, exiting, emitting, etc.) much terser and moves it to the end of the functions so it's less in your face. Never made much use of it, and it's so non-canonical that I'm loathe to advocate it too much, but it would make me happy some sort of standard syntactic sugar could be introduced that allowed comparable brevity.

Re:Node v6.9.0 (LTS) by _greim_ on Tuesday October 18, 2016 @06:59PM (#12739500)
> it is quite literally silently swallowing ALL exceptions thrown

Technically, it propagates the error along to any dependent promises. If nobody's handling errors, then yes, they get swallowed. If that bugs you, all you have to do is add this once when your app starts up:

    process.on('unhandledRejection', function(ex) {
      console.error(ex.stack);
      process.exit(1);
    });
I think that should have been the default, personally, but it's a nuisance at worst. Throwing out promises because of this is absurd thinking.
Re:Node v6.9.0 (LTS) by james-mcelwain on Tuesday October 18, 2016 @08:08PM (#12739848)
Killing a process on an exception you can't handle is sort of best practice anyway in Node--assuming you're not building important financial services or whatever in Node (lol).

Like, you want to be careful not to open yourself up to cascading failure, but if my application has a random exception, the 100ms start up time of the JavaScript VM means its almost always worth the cost of restarting to ensure your application isn't in an unstable state.

Re:Node v6.9.0 (LTS) by danneu on Tuesday October 18, 2016 @09:00PM (#12740107)
I'd rethink that. Every connection to the server closes, and whatever else it might be doing stops, because someone hits your syntax error? And they completely DoS your server by slowly refreshing the page?

Surely the best practice is to use something like koa or otherwise create a promise chain with a top-level 500 handler.

Re:Node v6.9.0 (LTS) by mnutt on Tuesday October 18, 2016 @10:09PM (#12740452)
Depending on how much state your applications carry forward, I think killing the process is often the right thing to do. Otherwise, it's very easy to end up with connection leaks or just downright confusing state that can't always easily be traced back to what should have been an exception.

I run a node app that serves ~500M requests a day that is configured to die on exceptions, it just means that we do everything we can to prevent them (unit tests, linters, etc) and take them very seriously when they happen.

Re:Node v6.9.0 (LTS) by Touche on Tuesday October 18, 2016 @08:51PM (#12740070)
What makes you think I can't handle it? I definitely can handle it, and Promises give me the ability to handle them.
Re:Node v6.9.0 (LTS) by nilliams on Wednesday October 19, 2016 @04:05AM (#12741965)
In my example I was talking about avoiding es6-promise polyfill in the browser, because of the fact that it adheres so strictly to the spec that it does not have an equivalent to the safety net you give in your Node example.
Re:Node v6.9.0 (LTS) by _greim_ on Friday October 21, 2016 @12:14AM (#12758109)
Yeah polyfills might not do the right thing. Natively, both exceptions and rejections stop the next thing from happening, give you a trace in the console, then everything continues at the next tick of the event loop. If a polyfill skips the trace part, that's definitely bad.
Re:Node v6.9.0 (LTS) by nilliams on Friday October 21, 2016 @03:48PM (#12763994)
Yep I know, I'm specifically complaining about the current trend of casting off old ajax methods/libraries and moving to 'fetch()' polyfills, as currently the 2 main popular fetch modules both recommend 'es6-promise' as polyfill which has serious problems in this regard: https://github.com/matthew-andrews/isomorphic-fetch/issues/1...

Technically however, what that polyfill is doing is 'on-spec'. Note that your `process.on('unhandledRejection')` thing is clearly outside spec as `process` is a Node thing, not a JS thing.

Re:Node v6.9.0 (LTS) by Touche on Tuesday October 18, 2016 @08:49PM (#12740059)
Personally I don't want my process to crash because I didn't handle some unimportant writeFile call correctly. This is why I use Promises, so I can handle exceptions.
Re:Node v6.9.0 (LTS) by aroc on Tuesday October 18, 2016 @03:07PM (#12737656)
I came to the comments section to post this exact comment. This is a hugely impactful change! Super happy to see this land.
Re:Node v6.9.0 (LTS) by CSDude on Tuesday October 18, 2016 @02:48PM (#12737466)
I wish the browsers moved on with the support as fast as Node so that we can get rid of stupid hundreds of MBs dependencies to transform a arrow function.
Re:Node v6.9.0 (LTS) by BinaryIdiot on Tuesday October 18, 2016 @03:45PM (#12737996)
So two things.

First, it doesn't matter how fast browsers moved. Currently they're moving pretty damn quick if you ask me but it doesn't matter because you need to know your audience and what browser(s) they use.

Second, I don't understand the want or need to include "hundreds of MBs dependencies to transform a arrow function". Why do you have to use an arrow function? Yeah it looks nicer but if you're complaining about how much dependency it brings in why not just not use it? Don't get me wrong I like ECMAScript 2015 but if you don't want to bring in the huge amount of transpiler dependencies ECMASCript 5 is still super easy to write.

Re:Node v6.9.0 (LTS) by algesten on Tuesday October 18, 2016 @04:51PM (#12738586)
Exactly my point. Arrow functions and destructuring assignments are great, but we've put up with function() { ... } for the last 20 years, so I'm pretty certain we can wait a couple of more years and not get bogged down in these crazy tooling chains to achieve so little.

and if we insist on crazy tooling chains, how about getting some real benefit – like coffeescript (?-operator anyone) or typescript (yes, typing can help, just look at swift)?

Re:Node v6.9.0 (LTS) by tracker1 on Tuesday October 18, 2016 @03:06PM (#12737650)
The engine that Node is using is already in chrome, and iirc all the major current versions of browsers already have 97% support (tail call opts withstanding, I think for safari this is still a vNext issue).

You can use one of a number of modern targets which will avoid the need for the various polyfils etc... but if you need current safari and any IE support, you will at least need dual build paths, which isn't too bad. I kind of wish there was a babel preset that was meant to be used in conjuction with Financial Times' polyfill.io

Re:Node v6.9.0 (LTS) by hzoo on Tuesday October 18, 2016 @03:09PM (#12737678)
I've been working on https://github.com/babel/babel-preset-env/ and there's a similar request although using babel-polyfill rather than the service https://github.com/babel/babel-preset-env/issues/20
Re:Node v6.9.0 (LTS) by minitech on Tuesday October 18, 2016 @02:51PM (#12737489)
Browsers already support arrow functions (and did before Node), but there’s no reason to break compatibility with old browsers just to get arrow functions.

If that’s the only thing you’re transforming, my advice would be to stop and just use function () {}.

Re:Node v6.9.0 (LTS) by TAForObvReasons on Tuesday October 18, 2016 @02:59PM (#12737576)
> we can get rid of stupid hundreds of MBs dependencies to transform a arrow function.

Depending on your target market, you may be stuck on ES5. Your users' browser behavior determines when you can remove the shims and transforms, and if they aren't upgrading you can't really force them to upgrade the browsers.

Re:Node v6.9.0 (LTS) by komali2 on Tuesday October 18, 2016 @06:33PM (#12739324)
>force them to upgrade their browsers

Please yes

Re:Node v6.9.0 (LTS) by qaq on Tuesday October 18, 2016 @03:06PM (#12737652)
Hmm Node is trailing chrome what exactly are you talking about?
Re:Node v6.9.0 (LTS) by tiglionabbit on Tuesday October 18, 2016 @04:28PM (#12738354)
They do. Try writing an arrow function into your browser's console right now.

http://caniuse.com/#feat=arrow-functions

Re:Node v6.9.0 (LTS) by scrabble on Tuesday October 18, 2016 @06:42PM (#12739376)
Bluebird already has this, and is more efficient than native. But this is definitely a step forward.
Re:Node v6.9.0 (LTS) by m1sta_ on Tuesday October 18, 2016 @09:48PM (#12740352)
I'm not debating the point, but how is that possible?
Re:Node v6.9.0 (LTS) by bananaoomarang on Wednesday October 19, 2016 @03:09AM (#12741713)
Re:Node v6.9.0 (LTS) by sotojuan on Wednesday October 19, 2016 @12:29AM (#12741071)
I'm not sure how it's possible but it's definitely not rare. Lodash' methods are faster than their respective native implementations (Lodash `map` > `Array.prototype.map`).
Re:Node v6.9.0 (LTS) by JaRail on Wednesday October 19, 2016 @03:11AM (#12741720)
As a general answer, doing something simple in pure JS can be more efficient than the overhead associated with making a native call from JS. The costs are going to vary depending on how the JIT handles things. That's probably the best general reason though as to how it's possible.
Re:Node v6.9.0 (LTS) by scrabble on Wednesday October 19, 2016 @01:24PM (#12745719)
As I understand it, native promises don't make native system calls. They are still pure js. They are just implemented differently from Bluebird which optimizes for the most common use cases.
Re:Node v6.9.0 (LTS) by STRiDEX on Tuesday October 18, 2016 @10:26PM (#12740519)
http://programmers.stackexchange.com/questions/278778/why-ar...

I'm not sure all of it still stands. Bluebird is in C. Native is in javascript.

Edit: i'm wrong

Re:Node v6.9.0 (LTS) by mscdex on Tuesday October 18, 2016 @11:06PM (#12740700)
Bluebird isn't written in C. It doesn't even depend on a compiled node addon.
Re:Node v6.9.0 (LTS) by STRiDEX on Wednesday October 19, 2016 @12:09AM (#12741005)
Re:Node v6.9.0 (LTS) by wmichelin on Tuesday October 18, 2016 @02:40PM (#12737396)
Sounds like a step in the right direction!