0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00
nodejs/test/parallel/test-fs-watch-enoent.js
Joyee Cheung 6c25f2ea49
fs: improve errors thrown from fs.watch()
- Add an accessor property `initialized `to FSEventWrap to
  check the state of the handle from the JS land
- Introduce ERR_FS_WATCHER_ALREADY_STARTED so calling start()
  on a watcher that is already started will throw instead of
  doing nothing silently.
- Introduce ERR_FS_WATCHER_NOT_STARTED so calling close()
  on a watcher that is already closed will throw instead of
  doing nothing silently.
- Validate the filename passed to fs.watch()
- Assert that the handle in the watcher are instances of
  FSEvent instead of relying on the illegal invocation error
  from the VM.
- Add more assertions in FSEventWrap methods now that we check
  `initialized` and the filename in JS land before invoking
  the binding.
- Use uvException instead of errornoException to create
  the errors with the error numbers from libuv to make them
  consistent with other errors in fs.

TODO:

- Improve fs.watchFile() the same way this patch improves fs.watch()
- It seems possible to fire both rename and change event from libuv
  together now that we can check if the handle is closed via
  `initialized` in JS land.

PR-URL: https://github.com/nodejs/node/pull/19089
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
2018-03-08 01:14:53 +08:00

65 lines
1.9 KiB
JavaScript

'use strict';
// This verifies the error thrown by fs.watch.
const common = require('../common');
const assert = require('assert');
const fs = require('fs');
const tmpdir = require('../common/tmpdir');
const path = require('path');
const nonexistentFile = path.join(tmpdir.path, 'non-existent');
const uv = process.binding('uv');
tmpdir.refresh();
{
const validateError = (err) => {
assert.strictEqual(err.path, nonexistentFile);
assert.strictEqual(err.filename, nonexistentFile);
assert.strictEqual(err.syscall, 'watch');
if (err.code === 'ENOENT') {
assert.strictEqual(
err.message,
`ENOENT: no such file or directory, watch '${nonexistentFile}'`);
assert.strictEqual(err.errno, uv.UV_ENOENT);
assert.strictEqual(err.code, 'ENOENT');
} else { // AIX
assert.strictEqual(
err.message,
`ENODEV: no such device, watch '${nonexistentFile}'`);
assert.strictEqual(err.errno, uv.UV_ENODEV);
assert.strictEqual(err.code, 'ENODEV');
}
return true;
};
assert.throws(
() => fs.watch(nonexistentFile, common.mustNotCall()),
validateError
);
}
{
const file = path.join(tmpdir.path, 'file-to-watch');
fs.writeFileSync(file, 'test');
const watcher = fs.watch(file, common.mustNotCall());
const validateError = (err) => {
assert.strictEqual(err.path, nonexistentFile);
assert.strictEqual(err.filename, nonexistentFile);
assert.strictEqual(
err.message,
`ENOENT: no such file or directory, watch '${nonexistentFile}'`);
assert.strictEqual(err.errno, uv.UV_ENOENT);
assert.strictEqual(err.code, 'ENOENT');
assert.strictEqual(err.syscall, 'watch');
fs.unlinkSync(file);
return true;
};
watcher.on('error', common.mustCall(validateError));
// Simulate the invocation from the binding
watcher._handle.onchange(uv.UV_ENOENT, 'ENOENT', nonexistentFile);
}