Skip to content

Commit

Permalink
fix: ensure error events are sent (#167)
Browse files Browse the repository at this point in the history
Signed-off-by: Jérôme Benoit <[email protected]>
  • Loading branch information
jerome-benoit authored Oct 27, 2024
1 parent 05c76c5 commit bde9951
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 24 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export interface Options {
signal?: AbortSignal;

/**
* Throw if a task fails (events will not work if true) @default false
* Throws if a task fails @default false
*/
throws?: boolean;

Expand Down Expand Up @@ -369,7 +369,7 @@ task.addEventListener('cycle', (evt) => {
### `BenchEvent`

```ts
export type BenchEvent = Event & { task?: Task };
export type BenchEvent = Event & { error?: Error; task?: Task };
```

### `process.hrtime`
Expand Down
4 changes: 2 additions & 2 deletions src/bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export default class Bench extends EventTarget {
const limit = pLimit(this.threshold);
const promises: Promise<void>[] = [];
for (const task of this._tasks.values()) {
promises.push(limit(() => task.warmup()));
promises.push(limit(task.warmup.bind(task)));
}
await Promise.all(promises);
} else {
Expand All @@ -124,7 +124,7 @@ export default class Bench extends EventTarget {
const limit = pLimit(this.threshold);
const promises: Promise<Task>[] = [];
for (const task of this._tasks.values()) {
promises.push(limit(() => task.run()));
promises.push(limit(task.run.bind(task)));
}
values = await Promise.all(promises);
} else {
Expand Down
20 changes: 18 additions & 2 deletions src/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,21 @@ function createBenchEvent(eventType: BenchEvents, target?: Task) {
return event;
}

// eslint-disable-next-line import/prefer-default-export
export { createBenchEvent };
function createErrorEvent(target: Task, error: Error) {
const event = new Event('error');
Object.defineProperty(event, 'task', {
value: target,
enumerable: true,
writable: false,
configurable: false,
});
Object.defineProperty(event, 'error', {
value: error,
enumerable: true,
writable: false,
configurable: false,
});
return event;
}

export { createBenchEvent, createErrorEvent };
10 changes: 5 additions & 5 deletions src/task.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pLimit from 'p-limit';
import type Bench from './bench';
import { createBenchEvent } from './event';
import { createBenchEvent, createErrorEvent } from './event';
import type {
AddEventListenerOptionsArgument,
Fn,
Expand Down Expand Up @@ -148,11 +148,11 @@ export default class Task extends EventTarget {

if (error) {
this.setResult({ error });
this.dispatchEvent(createErrorEvent(this, error));
this.bench.dispatchEvent(createErrorEvent(this, error));
if (this.bench.throws) {
throw error;
}
this.dispatchEvent(createBenchEvent('error', this));
this.bench.dispatchEvent(createBenchEvent('error', this));
}
}

Expand Down Expand Up @@ -217,11 +217,11 @@ export default class Task extends EventTarget {

if (error) {
this.setResult({ error });
this.dispatchEvent(createErrorEvent(this, error));
this.bench.dispatchEvent(createErrorEvent(this, error));
if (this.bench.throws) {
throw error;
}
this.dispatchEvent(createBenchEvent('error', this));
this.bench.dispatchEvent(createBenchEvent('error', this));
}

this.dispatchEvent(createBenchEvent('cycle', this));
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export type BenchEvents =

export type Hook = (task: Task, mode: 'warmup' | 'run') => void | Promise<void>;

export type BenchEvent = Event & { task?: Task };
export type BenchEvent = Event & { error?: Error; task?: Task };

export type EventListener = (evt: BenchEvent) => void;

Expand Down Expand Up @@ -334,7 +334,7 @@ export interface Options {
signal?: AbortSignal;

/**
* Throw if a task fails (events will not work if true) @default false
* Throws if a task fails @default false
*/
throws?: boolean;

Expand Down
35 changes: 24 additions & 11 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,23 @@ test('events order at task completion', async () => {

test.each(['warmup', 'run'])('%s error event', async (mode) => {
const bench = new Bench({ time: 100, warmup: mode === 'warmup' });
const err = new Error();
const error = new Error();

bench.add('error', () => {
throw err;
throw error;
});

let taskErr: Error | undefined;
let err: Error | undefined;
let task: Task | undefined;
bench.addEventListener('error', (evt) => {
const { task } = evt;
taskErr = task?.result?.error;
const { error: e, task: t } = evt;
err = e;
task = t;
});

await bench.run();

expect(taskErr).toStrictEqual(err);
await expect(bench.run()).resolves.toBeDefined();
expect(err).toStrictEqual(error);
expect(task?.result?.error).toStrictEqual(error);
});

test.each(['warmup', 'run'])('%s throws', async (mode) => {
Expand All @@ -223,12 +225,23 @@ test.each(['warmup', 'run'])('%s throws', async (mode) => {
warmup: mode === 'warmup',
warmupIterations: iterations,
});
const err = new Error();
const error = new Error();

bench.add('error', () => {
throw err;
throw error;
});
await expect(() => bench.run()).rejects.toThrowError(err);

let err: Error | undefined;
let task: Task | undefined;
bench.addEventListener('error', (evt) => {
const { error: e, task: t } = evt;
err = e;
task = t;
});

await expect(bench.run()).rejects.toThrowError(error);
expect(err).toStrictEqual(error);
expect(task?.result?.error).toStrictEqual(error);
});

test('detect faster task', async () => {
Expand Down

0 comments on commit bde9951

Please sign in to comment.