refactor: include the cause into locator abort and timeout errors (#12207)

This commit is contained in:
Alex Rudenko 2024-04-05 11:18:24 +02:00 committed by GitHub
parent bb10e45696
commit 17e9fee77b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 11 deletions

View File

@ -172,19 +172,23 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
}); });
}, },
retryAndRaceWithSignalAndTimer: <T>( retryAndRaceWithSignalAndTimer: <T>(
signal?: AbortSignal signal?: AbortSignal,
cause?: Error
): OperatorFunction<T, T> => { ): OperatorFunction<T, T> => {
const candidates = []; const candidates = [];
if (signal) { if (signal) {
candidates.push( candidates.push(
fromEvent(signal, 'abort').pipe( fromEvent(signal, 'abort').pipe(
map(() => { map(() => {
if (signal.reason instanceof Error) {
signal.reason.cause = cause;
}
throw signal.reason; throw signal.reason;
}) })
) )
); );
} }
candidates.push(timeout(this._timeout)); candidates.push(timeout(this._timeout, cause));
return pipe( return pipe(
retry({delay: RETRY_DELAY}), retry({delay: RETRY_DELAY}),
raceWith<T, never[]>(...candidates) raceWith<T, never[]>(...candidates)
@ -368,6 +372,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<LocatorClickOptions> options?: Readonly<LocatorClickOptions>
): Observable<void> { ): Observable<void> {
const signal = options?.signal; const signal = options?.signal;
const cause = new Error('Locator.click');
return this._wait(options).pipe( return this._wait(options).pipe(
this.operators.conditions( this.operators.conditions(
[ [
@ -388,7 +393,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
}) })
); );
}), }),
this.operators.retryAndRaceWithSignalAndTimer(signal) this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
); );
} }
@ -398,6 +403,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<ActionOptions> options?: Readonly<ActionOptions>
): Observable<void> { ): Observable<void> {
const signal = options?.signal; const signal = options?.signal;
const cause = new Error('Locator.fill');
return this._wait(options).pipe( return this._wait(options).pipe(
this.operators.conditions( this.operators.conditions(
[ [
@ -521,7 +527,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
}) })
); );
}), }),
this.operators.retryAndRaceWithSignalAndTimer(signal) this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
); );
} }
@ -530,6 +536,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<ActionOptions> options?: Readonly<ActionOptions>
): Observable<void> { ): Observable<void> {
const signal = options?.signal; const signal = options?.signal;
const cause = new Error('Locator.hover');
return this._wait(options).pipe( return this._wait(options).pipe(
this.operators.conditions( this.operators.conditions(
[ [
@ -549,7 +556,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
}) })
); );
}), }),
this.operators.retryAndRaceWithSignalAndTimer(signal) this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
); );
} }
@ -558,6 +565,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<LocatorScrollOptions> options?: Readonly<LocatorScrollOptions>
): Observable<void> { ): Observable<void> {
const signal = options?.signal; const signal = options?.signal;
const cause = new Error('Locator.scroll');
return this._wait(options).pipe( return this._wait(options).pipe(
this.operators.conditions( this.operators.conditions(
[ [
@ -590,7 +598,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
}) })
); );
}), }),
this.operators.retryAndRaceWithSignalAndTimer(signal) this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
); );
} }
@ -617,9 +625,10 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
* @public * @public
*/ */
async waitHandle(options?: Readonly<ActionOptions>): Promise<HandleFor<T>> { async waitHandle(options?: Readonly<ActionOptions>): Promise<HandleFor<T>> {
const cause = new Error('Locator.waitHandle');
return await firstValueFrom( return await firstValueFrom(
this._wait(options).pipe( this._wait(options).pipe(
this.operators.retryAndRaceWithSignalAndTimer(options?.signal) this.operators.retryAndRaceWithSignalAndTimer(options?.signal, cause)
) )
); );
} }

View File

@ -13,8 +13,8 @@ export class PuppeteerError extends Error {
/** /**
* @internal * @internal
*/ */
constructor(message?: string) { constructor(message?: string, options?: ErrorOptions) {
super(message); super(message, options);
this.name = this.constructor.name; this.name = this.constructor.name;
} }

View File

@ -312,12 +312,12 @@ export function validateDialogType(
/** /**
* @internal * @internal
*/ */
export function timeout(ms: number): Observable<never> { export function timeout(ms: number, cause?: Error): Observable<never> {
return ms === 0 return ms === 0
? NEVER ? NEVER
: timer(ms).pipe( : timer(ms).pipe(
map(() => { map(() => {
throw new TimeoutError(`Timed out after waiting ${ms}ms`); throw new TimeoutError(`Timed out after waiting ${ms}ms`, {cause});
}) })
); );
} }