Skip to content

Commit 34bc428

Browse files
Skn0ttCopilot
andauthored
fix(core): surface abort reasons in errors (#41752)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 7b02a7a commit 34bc428

5 files changed

Lines changed: 12 additions & 11 deletions

File tree

packages/playwright-core/src/server/dispatchers/dispatcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ export class DispatcherConnection {
312312
return;
313313
}
314314
if (method === '__abort__') {
315-
await this._activeProgressControllers.get(`call@${params.id}`)?.abort(new AbortError(undefined, { cause: params.reason }));
315+
await this._activeProgressControllers.get(`call@${params.id}`)?.abort(new AbortError(params.reason));
316316
return;
317317
}
318318
if (!dispatcher) {

packages/playwright-core/src/server/frames.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
*/
1717

1818
import yaml from 'yaml';
19-
import { assertionAbortedMessage } from '@isomorphic/abortSignal';
2019
import { parseAriaSnapshotUnsafe } from '@isomorphic/ariaSnapshot';
2120
import { isInvalidSelectorError } from '@isomorphic/selectorParser';
2221
import { ManualPromise } from '@isomorphic/manualPromise';
@@ -29,7 +28,7 @@ import { makeWaitForNextTask } from '@utils/task';
2928
import { createGuid } from '@utils/crypto';
3029
import { BrowserContext } from './browserContext';
3130
import * as dom from './dom';
32-
import { TimeoutError, AbortError, isTargetClosedError } from './errors';
31+
import { TimeoutError, isTargetClosedError } from './errors';
3332
import { prepareFilesForUpload } from './fileUploadUtils';
3433
import { FrameSelectors } from './frameSelectors';
3534
import { helper } from './helper';
@@ -1546,8 +1545,6 @@ export class Frame extends SdkObject<FrameEventMap> {
15461545
progress.log(e.message);
15471546
if (e instanceof TimeoutError)
15481547
details.timedOut = true;
1549-
if (e instanceof AbortError)
1550-
details.customErrorMessage = assertionAbortedMessage(e.cause);
15511548
throw new ExpectError(details);
15521549
}
15531550
}

packages/playwright-core/src/server/progress.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,16 @@ export class ProgressController {
6262
});
6363
}
6464

65-
6665
async abort(error: Error) {
66+
const logMessage = `operation was aborted: ${error.message}`;
6767
if (this._state === 'running') {
68+
this.metadata.log.push(logMessage);
6869
(error as any)[kAbortErrorSymbol] = true;
6970
this._state = { error };
7071
this._forceAbortPromise.reject(error);
7172
this._controller.abort(error);
7273
} else if (this._state === 'before') {
74+
this.metadata.log.push(logMessage);
7375
(error as any)[kAbortErrorSymbol] = true;
7476
this._pendingAbortError = error;
7577
}

tests/page/expect-timeout.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,12 @@ test('should fail like a timeout when the signal is aborted mid-assertion', asyn
133133
134134
Locator: locator('span')
135135
Expected: visible
136-
Error: The assertion was aborted: stop it
136+
Error: element(s) not found
137137
138138
Call log:
139139
- Expect "toBeVisible" with timeout 5000ms
140-
- waiting for locator('span')`);
140+
- waiting for locator('span')
141+
- operation was aborted: stop it`);
141142
});
142143

143144
test('should fail like a timeout when toHaveText is aborted mid-assertion', async ({ page }) => {

tests/page/page-click.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,11 +1368,11 @@ it('should abort via signal', async ({ page }) => {
13681368
// Give the action time to start and emit call log entries before aborting.
13691369
await page.waitForTimeout(500);
13701370

1371-
const reason = new Error('Aborted by user');
1371+
const reason = new Error('foo bar');
13721372
controller.abort(reason);
13731373
const error = await promise;
1374-
expect(error.message).toContain('The operation was aborted');
1375-
expect(error.message).toContain(`Call log:`);
1374+
expect(error.message).toContain('locator.click: foo bar');
1375+
expect(error.message).toMatch(/Call log:[\s\S]*operation was aborted: foo bar/);
13761376
expect(error.name).toBe('AbortError');
13771377
expect(error.cause).toBe(reason);
13781378
});
@@ -1384,6 +1384,7 @@ it('should throw an Error when aborted in-flight with a string reason', async ({
13841384
controller.abort('aborted by user');
13851385
const error = await promise.catch(e => e);
13861386
expect(error).toBeInstanceOf(Error);
1387+
expect(error.message).toContain('locator.click: aborted by user');
13871388
expect(error.name).toBe('AbortError');
13881389
expect(error.cause).toBe('aborted by user');
13891390
});

0 commit comments

Comments
 (0)