-
Notifications
You must be signed in to change notification settings - Fork 7.3k
timers: force timeout to signed int in enroll() #8739
Conversation
This is a really important fix. The fact that |
@cjihrig I agree that this change fixes #8618, but it still makes Same question for |
@misterdjules 👍 for throwing for non-numbers. thats an even better idea. |
@misterdjules updated to throw on non numeric input in both functions. EDIT: I think it might be good to leave the case to a signed int in place (I removed it in the latest commit). But I think it would help with |
@@ -305,6 +305,9 @@ Socket.prototype.listen = function() { | |||
|
|||
|
|||
Socket.prototype.setTimeout = function(msecs, callback) { | |||
if (typeof msecs !== 'number') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After giving it more thought, it seems that this test would throw on all invalid use cases:
if (!util.isNumber(msecs) || !isFinite(msecs) || msecs < 0)
throw new TypeError('msecs must be a non-negative finite number');
Using util.isNumber
makes it more consistent with the rest of the code base.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for using util.isNumber
+1 for throwing on negative and not finite values, although I think RangeError would be more appropriate in that case (so it would need two separate checks).
@cjihrig Thank you very much for taking the time to update this PR. I think it's getting better. I think that Also thank you @Raynos for your feedback. it is very much appreciated! |
@trevnorris @tjfontaine can you weigh in here? @misterdjules and I were discussing the best way to handle edge cases. Specifically, timeouts < 0, Infinity, and NaN. Current behavior is to silently ignore. Should we begin throwing on these? |
@cjihrig I recommend doing a simple range check and function n(fn, timeout) {
if (timeout < 0) timeout = 0;
timeout = timeout >>> 0;
... EDIT: To elaborate, I don't believe throwing is a good idea. For kicks, I may want to pass a numeric string like |
@misterdjules does this work for you? If so, I'll update the code. |
@trevnorris What don't you like about throwing an error in this case? I have the same opinion as before. I agree that coercing In this specific case, if someone passes a string that cannot be converted to a number to Do we have general guidelines on how our APIs should handle erroneous programmer input? I like the idea of failing as early as possible. In my opinion, it makes troubleshooting issues way easier.
We could make this PR just coerce If we're concerned with backward compatibility, then maybe we could land a fix that only coerces the delay in v0.10, and another one that throws errors for any erroneous programmer input in v0.12 or later? |
I don’t want to stop anyone from making progress though, I just want to make sure that we explore the opportunity of making this API more robust. I would be fine with exploring that in an unstable branch. |
@tjfontaine @chrisdickinson @orangemocha @indutny Your input would be appreciated! :) |
I did not consider that the timeout is removed in the case where the Socket.prototype.setTimeout = function(msecs, callback) {
if (msecs >>> 0 != msecs)
throw new TypeError('msecs should be uint32');
msecs = msecs >>> 0; That will handle everything that doesn't convert properly ( |
I agree, lets take this time to make this interface crisp. The API clearly only takes a positive number, invalid type inputs should generate For what it's worth coercion in our APIs is often the root of subtle unfortunate bugs, in this particular case it's very difficult to believe passing a string to the API was what they actually meant to do (even if that string would parse to a valid number). But the good news is it's always easier to relax that constraint later than it is to make it more restrictive. |
+1 for throwing on invalid input in general. I would suggest throwing RangeError for non-positive or non-finite numbers (but TypeError for non numeric arguments). |
Closing as this is against master. Will open a new PR against 0.12 based on feedback and reference this PR. Thanks! |
Closes #8618