Skip to content

Commit 9d3b44b

Browse files
committed
feat: suppress eacces option
1 parent 096a5b6 commit 9d3b44b

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ This package provides methods for traversing the file system and returning pathn
3333
* [fs](#fs)
3434
* [ignore](#ignore)
3535
* [suppressErrors](#suppresserrors)
36+
* [errorHandler](#errorhandler)
3637
* [throwErrorOnBrokenSymbolicLink](#throwerroronbrokensymboliclink)
3738
* [signal](#signal)
3839
* [Output control](#output-control)
@@ -393,10 +394,28 @@ fg.globSync('*.json', { ignore: ['package-lock.json'] }); // ['package.json']
393394
* Type: `boolean`
394395
* Default: `false`
395396

396-
By default this package suppress only `ENOENT` errors. Set to `true` to suppress any error.
397+
By default this package suppress `ENOENT` errors. Set to `true` to suppress any error.
397398

398399
> :book: Can be useful when the directory has entries with a special level of access.
399400
401+
#### errorHandler
402+
403+
* Type: function (error: ErrnoException) => void
404+
405+
Supply a custom error handler that takes the error as argument and allows you to handle errors in a custom way.
406+
407+
```js
408+
fg.globSync('**', {
409+
errorHandler: (error) => {
410+
if (error.code === 'ENOENT') {
411+
console.error('Directory not found:', error.path);
412+
} else {
413+
console.error('Error:', error.message);
414+
}
415+
}
416+
});
417+
```
418+
400419
#### throwErrorOnBrokenSymbolicLink
401420

402421
* Type: `boolean`

src/providers/filters/error.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ export default class ErrorFilter {
1515
}
1616

1717
#isNonFatalError(error: ErrnoException): boolean {
18-
return utils.errno.isEnoentCodeError(error) || this.#settings.suppressErrors;
18+
if (this.#settings.suppressErrors) {
19+
return true;
20+
}
21+
22+
if (this.#settings.errorHandler !== undefined) {
23+
return this.#settings.errorHandler(error);
24+
}
25+
26+
if (utils.errno.isEnoentCodeError(error)) {
27+
return true;
28+
}
29+
30+
return false;
1931
}
2032
}

src/readers/reader.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ export abstract class Reader<T> {
4444
}
4545

4646
protected _isFatalError(error: ErrnoException): boolean {
47-
return !utils.errno.isEnoentCodeError(error) && !this.#settings.suppressErrors;
47+
if (this.#settings.suppressErrors) {
48+
return false;
49+
}
50+
51+
if (this.#settings.errorHandler !== undefined) {
52+
return !this.#settings.errorHandler(error);
53+
}
54+
55+
if (utils.errno.isEnoentCodeError(error)) {
56+
return false;
57+
}
58+
59+
return true;
4860
}
4961
}

src/settings.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe('Settings', () => {
1818
assert.ok(!settings.onlyDirectories);
1919
assert.ok(!settings.stats);
2020
assert.ok(!settings.suppressErrors);
21+
assert.ok(!settings.errorHandler);
2122
assert.ok(!settings.throwErrorOnBrokenSymbolicLink);
2223
assert.ok(settings.braceExpansion);
2324
assert.ok(settings.caseSensitiveMatch);

src/settings.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as fs from 'node:fs';
22

3-
import type { FileSystemAdapter, Pattern } from './types';
3+
import type { ErrnoException, FileSystemAdapter, Pattern } from './types';
44

55
export const DEFAULT_FILE_SYSTEM_ADAPTER: FileSystemAdapter = {
66
lstat: fs.lstat,
@@ -125,6 +125,13 @@ export interface Options {
125125
* @default false
126126
*/
127127
suppressErrors?: boolean;
128+
/**
129+
* Callback for user-defined error handling. Ignored if
130+
* `suppressErrors` is `true`. Return `true` to suppress an error,
131+
* `false` to throw it.
132+
*
133+
*/
134+
errorHandler?: (error: Error) => boolean;
128135
/**
129136
* Throw an error when symbolic link is broken if `true` or safely
130137
* return `lstat` call if `false`.
@@ -166,6 +173,7 @@ export default class Settings {
166173
public readonly onlyFiles: boolean;
167174
public readonly stats: boolean;
168175
public readonly suppressErrors: boolean;
176+
public readonly errorHandler: ((error: ErrnoException) => boolean) | undefined;
169177
public readonly throwErrorOnBrokenSymbolicLink: boolean;
170178
public readonly unique: boolean;
171179
public readonly signal?: AbortSignal;
@@ -190,7 +198,8 @@ export default class Settings {
190198
this.onlyFiles = options.onlyFiles ?? true;
191199
this.stats = options.stats ?? false;
192200
this.suppressErrors = options.suppressErrors ?? false;
193-
this.throwErrorOnBrokenSymbolicLink = options.throwErrorOnBrokenSymbolicLink ?? false;
201+
this.errorHandler = options.errorHandler ?? undefined;
202+
this.throwErrorOnBrokenSymbolicLink = options.throwErrorOnBrokenSymbolicLink ?? false;
194203
this.unique = options.unique ?? true;
195204
this.signal = options.signal;
196205

0 commit comments

Comments
 (0)