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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ setTimeout(() => query.cancel(), 100)
const result = await query
```

`query.cancel()` returns a promise that settles when the cancel request is done. It rejects if the request could not be sent, for example when a connection for it cannot be opened, so handle it to avoid an unhandled rejection. Calling it again returns the same promise.

### Execute

#### ```await sql``.execute()```
Expand Down
2 changes: 1 addition & 1 deletion src/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class Query extends Promise {
}

cancel() {
return this.canceller && (this.canceller(this), this.canceller = null)
return this.cancelling || (this.cancelling = this.canceller && this.canceller(this))
}

simple() {
Expand Down
25 changes: 25 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2302,6 +2302,31 @@ t('Cancel queued query', async() => {
return ['57014', error.code]
})

t('Cancel returns a promise that rejects when the cancel request fails', async() => {
let sockets = 0
const sql = postgres({
...options,
socket: () => {
if (sockets++)
throw new Error('no socket for the cancel request')
return new Promise((resolve, reject) => {
const socket = new net.Socket()
socket.connect(5432)
socket.on('error', reject)
socket.on('connect', () => resolve(socket))
})
}
})
await sql`select 1`
const query = sql`select pg_sleep(0.2)`.execute()
await delay(50)
const cancelled = query.cancel()
const rejected = await cancelled.then(() => false, e => e instanceof Error)
await query
await sql.end()
return ['true,true', [rejected, query.cancel() === cancelled].join()]
})

t('Fragments', async() => [
1,
(await sql`
Expand Down
6 changes: 5 additions & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,11 @@ declare namespace postgres {
writable(): Promise<Writable>;

execute(): this;
cancel(): void;
/**
* Sends a cancel request for this query, once, however often it is called
* @returns A promise that settles when the cancel request is done, and rejects if it could not be sent
*/
cancel(): Promise<void>;

/**
* @deprecated `.stream` has been renamed to `.forEach`
Expand Down