Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix throwing RangeError on invalid date output #6469

Closed
wants to merge 2 commits into from
Closed

fix throwing RangeError on invalid date output #6469

wants to merge 2 commits into from

Conversation

rumkin
Copy link
Contributor

@rumkin rumkin commented Apr 29, 2016

Checklist
  • tests and code linting passes
  • a test and/or benchmark is included
  • documentation is changed or added
  • the commit message follows commit guidelines
Affected core subsystem(s)
Description of change

Invalid date value throws RangeError on output with console.log or util.inspect.

Invalid date value throws RangeError on output with `console.log` or `util.inspect`.
@phillipj phillipj added the util Issues and PRs related to the built-in util module. label Apr 29, 2016
@addaleax
Copy link
Member

Thank you! Could you maybe also write a test for this? The CONTRIBUTING.md contains some info on that.

if (value.toString() === 'Invalid Date') {
return ctx.stylize('Invalid Date', 'date');
}
else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this pass make lint? The else should go on the previous line with the closing curly brace. Actually, core style is to leave off the braces all together in cases like this.

@addaleax
Copy link
Member

@rumkin Thanks for the changes! We don’t get notified when commits are added to PRs, so feel free to write a short message here whenever you do to let others know.

Have you had any luck writing a test? If you don’t have the time for that, that’s fine and can happen separately, I think.

@@ -304,7 +304,11 @@ function formatValue(ctx, value, recurseTimes) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toISOString.call(value), 'date');
if (value.toString() === 'Invalid Date') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, checking isNaN(value) should also work here since Date.prototype.valueOf() will return NaN when the date is invalid.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that’s changed to isNaN(value), I’d like to see a comment explaining more or less exactly what @jasnell just wrote. :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:-) not saying that it needs to be changed, only that it should work ;-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Number.isNaN(value.valueOf()) seems like the better way to go to me, even if it does require a code comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather see value.getTime() and compare that to an invalid date's getTime() that way it's obvious and no comment is required.

const invalidDate = Date.parse("invalid-date-string");
...
// later on
 if (isDate(value)) {
    if(Object.is(value.getTime(), invalidDate.getTime()) {
    //...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Insofar that it matters, the way V8 implements the Date object, getTime() is faster than valueOf() is faster than toString(). The first one is a field lookup, the others are calls into the runtime, with toString() polluting the date cache and creating a new string every time.

I'd write it as Number.isNaN(value.getTime()) or Object.is(value.getTime(), NaN) to avoid keeping around an extra object, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me.
On Apr 30, 2016 3:05 AM, "Ben Noordhuis" notifications@github.com wrote:

In lib/util.js
#6469 (comment):

@@ -304,7 +304,11 @@ function formatValue(ctx, value, recurseTimes) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {

  •  return ctx.stylize(Date.prototype.toISOString.call(value), 'date');
    
  •  if (value.toString() === 'Invalid Date') {
    

Insofar that it matters, the way V8 implements the Date object, getTime()
is faster than valueOf() is faster than toString(). The first one is a
field lookup, the others are calls into the runtime, with toString()
polluting the date cache and creating a new string every time.

I'd write it as Number.isNaN(value.getTime()) or Object.is(value.getTime(),
NaN) to avoid keeping around an extra object, though.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/nodejs/node/pull/6469/files/b23061713ea4c52d1280ca5f5d015aa92a62d529#r61667758

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnoordhuis well, it means keeping an extra date object once. It can be kept in a utility and used everywhere invalid dates are needed :P

I'm fine with Number.isNaN(value.getTime(), NaN) although it's not obvious to readers who are not familiar with this obscure detail.

@cjihrig
Copy link
Contributor

cjihrig commented Apr 29, 2016

@rumkin if you're looking for the right place to add a test,

assert.equal(util.inspect(new Date('Sun, 14 Feb 2010 11:48:40 GMT')),
new Date('2010-02-14T12:48:40+01:00').toISOString());
, seems appropriate :-)

@cjihrig
Copy link
Contributor

cjihrig commented May 1, 2016

Closing in favor of #6504

@cjihrig cjihrig closed this May 1, 2016
@rumkin
Copy link
Contributor Author

rumkin commented May 1, 2016

I removed pull request repo accidentally. This pull request is duplicate with changes by @bnoordhuis and tests.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants