Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ This package provides methods for traversing the file system and returning pathn
* [fs](#fs)
* [ignore](#ignore)
* [suppressErrors](#suppresserrors)
* [errorHandler](#errorhandler)
* [throwErrorOnBrokenSymbolicLink](#throwerroronbrokensymboliclink)
* [signal](#signal)
* [Output control](#output-control)
Expand Down Expand Up @@ -393,10 +394,32 @@ fg.globSync('*.json', { ignore: ['package-lock.json'] }); // ['package.json']
* Type: `boolean`
* Default: `false`

By default this package suppress only `ENOENT` errors. Set to `true` to suppress any error.
By default this package suppress `ENOENT` errors. Set to `true` to suppress any error.

> :book: Can be useful when the directory has entries with a special level of access.

#### errorHandler

* Type: function (error: ErrnoException) => boolean

Supply a custom error handler that takes the error as argument and allows you to
handle errors in a custom way. Return `true` to suppress the error,
`false` to throw the error.

```js
fg.globSync('**', {
errorHandler: (error) => {
if (error.code === 'ENOENT') {
console.error('Directory not found:', error.path);
return true;
} else {
console.error('Error:', error.message);
return false;
}
}
});
```

#### throwErrorOnBrokenSymbolicLink

* Type: `boolean`
Expand Down
14 changes: 13 additions & 1 deletion src/providers/filters/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ export default class ErrorFilter {
}

#isNonFatalError(error: ErrnoException): boolean {
return utils.errno.isEnoentCodeError(error) || this.#settings.suppressErrors;
if (this.#settings.suppressErrors) {
return true;
}

if (this.#settings.errorHandler !== undefined) {
return this.#settings.errorHandler(error);
}

if (utils.errno.isEnoentCodeError(error)) {
return true;
}

return false;
}
}
14 changes: 13 additions & 1 deletion src/readers/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ export abstract class Reader<T> {
}

protected _isFatalError(error: ErrnoException): boolean {
return !utils.errno.isEnoentCodeError(error) && !this.#settings.suppressErrors;
if (this.#settings.suppressErrors) {
return false;
}

if (this.#settings.errorHandler !== undefined) {
return !this.#settings.errorHandler(error);
}

if (utils.errno.isEnoentCodeError(error)) {
return false;
}

return true;
}
}
1 change: 1 addition & 0 deletions src/settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('Settings', () => {
assert.ok(!settings.onlyDirectories);
assert.ok(!settings.stats);
assert.ok(!settings.suppressErrors);
assert.ok(!settings.errorHandler);
assert.ok(!settings.throwErrorOnBrokenSymbolicLink);
assert.ok(settings.braceExpansion);
assert.ok(settings.caseSensitiveMatch);
Expand Down
13 changes: 11 additions & 2 deletions src/settings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fs from 'node:fs';

import type { FileSystemAdapter, Pattern } from './types';
import type { ErrnoException, FileSystemAdapter, Pattern } from './types';

export const DEFAULT_FILE_SYSTEM_ADAPTER: FileSystemAdapter = {
lstat: fs.lstat,
Expand Down Expand Up @@ -125,6 +125,13 @@ export interface Options {
* @default false
*/
suppressErrors?: boolean;
/**
* Callback for user-defined error handling. Ignored if
* `suppressErrors` is `true`. Return `true` to suppress an error,
* `false` to throw it.
*
*/
errorHandler?: (error: Error) => boolean;
/**
* Throw an error when symbolic link is broken if `true` or safely
* return `lstat` call if `false`.
Expand Down Expand Up @@ -166,6 +173,7 @@ export default class Settings {
public readonly onlyFiles: boolean;
public readonly stats: boolean;
public readonly suppressErrors: boolean;
public readonly errorHandler: ((error: ErrnoException) => boolean) | undefined;
public readonly throwErrorOnBrokenSymbolicLink: boolean;
public readonly unique: boolean;
public readonly signal?: AbortSignal;
Expand All @@ -190,7 +198,8 @@ export default class Settings {
this.onlyFiles = options.onlyFiles ?? true;
this.stats = options.stats ?? false;
this.suppressErrors = options.suppressErrors ?? false;
this.throwErrorOnBrokenSymbolicLink = options.throwErrorOnBrokenSymbolicLink ?? false;
this.errorHandler = options.errorHandler ?? undefined;
this.throwErrorOnBrokenSymbolicLink = options.throwErrorOnBrokenSymbolicLink ?? false;
this.unique = options.unique ?? true;
this.signal = options.signal;

Expand Down