-
Notifications
You must be signed in to change notification settings - Fork 30k
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
fs: throw errors on invalid paths synchronously #18308
Conversation
@@ -101,26 +101,6 @@ common.expectsError(() => { | |||
); | |||
}); | |||
|
|||
// Throws if the source path is an invalid path. |
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.
This is removed because there are checks in test-fs-null-bytes.js
lib/fs.js
Outdated
@@ -204,6 +204,37 @@ function validateOffsetLengthWrite(offset, length, byteLength) { | |||
} | |||
} | |||
|
|||
// Returns silently if path contains null bytes. |
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.
Oops, should've been Check if the path contains null types if it is a string nor Uint8Array, otherwise return silently
.
@joyeecheung - Will this cause a previously working code that received a propagated error message in the API's callback to now synchronously throw an error? I guess the decision to throw inline or async or error-flled callback may be taken based the API interface itself, rather than the type of the error we are dealing with? |
@gireeshpunathil But we do throw type-checking errors and range errors synchronously in almost all of our APIs at the moment, even in the async APIs, so the users should always be prepared for both types of errors even without this change. Aside from The URL type errors and null check errors IMO are not that far from type errors and range errors, it's rather surprising that some of them are thrown asynchronously while some of them are not. Deferring them to the next tick does not seem to yield any benefit so if we are unifying the behavior, we might as well throw them synchronously. |
thanks @joyeecheung . Neither I have a full view of the existing behavior, documented evidence to support them, nor any specific concerns on this PR. But In general, I think it is a good idea for an async API to call back under all possible circumstances, except from native assertions and machine check exceptions - will you please spawn a separate thread to gather views and reach consensus? |
cc @nodejs/tsc since it's semver-major |
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.
I agree with this change.
LGTM with the FIXME addressed.
lib/fs.js
Outdated
const err = new errors.Error('ERR_INVALID_ARG_TYPE', | ||
propName, | ||
'string without null bytes', | ||
path); |
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.
I do not like leaving FIXME in the code, can you get this sorted?
@mcollina Was going to fix that later, but I am fine with fixing it now as well. Updated, PTAL. |
LGTM |
ab32b24
to
03b0f73
Compare
Rebased. New CI: https://ci.nodejs.org/job/node-test-pull-request/12706/ |
cc @nodejs/tsc this needs at least one more approval to land, although we might want to discuss about it in a meeting. cons:
pros:
Also see #18308 (comment) on the special case of |
CITGM against master: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/1228/ |
2cf2fdb
to
354c61d
Compare
Updated:
|
cc @jasnell @mcollina Please take another look since the behavior of
|
CI: https://ci.nodejs.org/job/node-test-pull-request/12720/ |
lib/internal/errors.js
Outdated
} | ||
return util_; | ||
} | ||
|
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.
Using the other lazy require is faster. It is probably not much of a difference in the real world but I would still prefer to keep it as is.
lib/internal/errors.js
Outdated
E('ERR_INVALID_ARG_VALUE', (name, value) => | ||
`The value "${String(value)}" is invalid for argument "${name}"`); | ||
E('ERR_INVALID_ARG_VALUE', (name, value, reason = 'is invalid') => { | ||
const util = lazyUtil(); |
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.
This is not necessary in case you assign util to a "global" (module) variable. In that case util will always be loaded before the error here can be called. That is another reason why I would prefer to keep the old lazy loading.
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.
354c61d
to
c1702d9
Compare
Rebased. CI: https://ci.nodejs.org/job/node-test-pull-request/12902/ @BridgeAR See #18308 (comment) about the |
CI is unstable today...launched two builds and the combination look green... https://ci.nodejs.org/job/node-test-pull-request/12903/ (ubuntu1604-arm64_odroid_c2 and osx1010 infra issue) |
CITGM against master: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/1253/ |
There don't seem to be new errors from the CITGM run. The errors that did not appear on master appear on other PRs' CITGM runs. cc @mcollina @jasnell @gireeshpunathil @BridgeAR @Trott any more thoughts on this PR? The only significant change is that we don't throw in |
Also @mcollina @jasnell @gireeshpunathil To people who have already signed-off on this, does this still LGTY? I would like to land this soon so I can continue to work on improving the async errors' stack traces. |
Still LGTM. |
still LGTM |
- Throw getPathFromURL() and nullCheck() errors synchronously instead of deferring them to the next tick, since we already throw validatePath() errors synchronously. - Merge nullCheck() into validatePath() - Never throws in `fs.exists()`, instead, invoke the callback with false, or emit a warning when the callback is not a function. This is to bring it inline with fs.existsSync(), which never throws. - Updates the comment of rethrow() - Throw ERR_INVALID_ARG_VALUE for null checks
bcf05af
to
758edd3
Compare
CI is clean minus one infra issue. Landing.. |
Landed in d8f7338, thanks! |
- Throw getPathFromURL() and nullCheck() errors synchronously instead of deferring them to the next tick, since we already throw validatePath() errors synchronously. - Merge nullCheck() into validatePath() - Never throws in `fs.exists()`, instead, invoke the callback with false, or emit a warning when the callback is not a function. This is to bring it inline with fs.existsSync(), which never throws. - Updates the comment of rethrow() - Throw ERR_INVALID_ARG_VALUE for null checks PR-URL: #18308 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
- Throw getPathFromURL() and nullCheck() errors synchronously instead of deferring them to the next tick, since we already throw validatePath() errors synchronously. - Merge nullCheck() into validatePath() - Never throws in `fs.exists()`, instead, invoke the callback with false, or emit a warning when the callback is not a function. This is to bring it inline with fs.existsSync(), which never throws. - Updates the comment of rethrow() - Throw ERR_INVALID_ARG_VALUE for null checks PR-URL: nodejs#18308 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Since type check errors on paths are throw synchronously, it makes more sense to throw other types of checks on the paths synchronously as well.
fs: throw errors on invalid paths synchronously
of deferring them to the next tick, since we already throw
validatePath() errors synchronously.
fs.exists()
, instead, invoke the callback withfalse, or emit a warning when the callback is not a function.
This is to bring it inline with fs.existsSync(), which never throws.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
fs, whatwg-url