diff --git a/cf/src/query.js b/cf/src/query.js index 0d44a15c..02ad6f36 100644 --- a/cf/src/query.js +++ b/cf/src/query.js @@ -84,9 +84,15 @@ export class Query extends Promise { return (this.cursorFn = fn, this) let prev + , error = null return { [Symbol.asyncIterator]: () => ({ next: () => { + if (error) { + const err = error + error = null + return Promise.reject(err) + } if (this.executed && !this.active) return { done: true } @@ -97,7 +103,7 @@ export class Query extends Promise { return new Promise(r => prev = r) } this.resolve = () => (this.active = false, resolve({ done: true })) - this.reject = x => (this.active = false, reject(x)) + this.reject = x => (this.active = false, error = x, reject(x)) }) this.execute() return promise diff --git a/cjs/src/query.js b/cjs/src/query.js index 45327f2f..d40dbb6c 100644 --- a/cjs/src/query.js +++ b/cjs/src/query.js @@ -84,9 +84,15 @@ const Query = module.exports.Query = class Query extends Promise { return (this.cursorFn = fn, this) let prev + , error = null return { [Symbol.asyncIterator]: () => ({ next: () => { + if (error) { + const err = error + error = null + return Promise.reject(err) + } if (this.executed && !this.active) return { done: true } @@ -97,7 +103,7 @@ const Query = module.exports.Query = class Query extends Promise { return new Promise(r => prev = r) } this.resolve = () => (this.active = false, resolve({ done: true })) - this.reject = x => (this.active = false, reject(x)) + this.reject = x => (this.active = false, error = x, reject(x)) }) this.execute() return promise diff --git a/cjs/tests/index.js b/cjs/tests/index.js index 85d1aa46..c05a31ba 100644 --- a/cjs/tests/index.js +++ b/cjs/tests/index.js @@ -1457,6 +1457,21 @@ t('Async Iterator Cursor custom with less results than batch size', async() => { return ['20', order.join(',')] }) +t('Async Iterator Cursor surfaces error arriving between batches', async() => { + const query = sql`select * from generate_series(1,5) as x` + const iterator = query.cursor(1)[Symbol.asyncIterator]() + await iterator.next() + query.reject(new Error('between-batch')) + let caught + try { + await iterator.next() + } catch (err) { + caught = err.message + } + await iterator.return() + return ['between-batch', caught] +}) + t('Transform row', async() => { const sql = postgres({ ...options, diff --git a/deno/src/query.js b/deno/src/query.js index 0d44a15c..02ad6f36 100644 --- a/deno/src/query.js +++ b/deno/src/query.js @@ -84,9 +84,15 @@ export class Query extends Promise { return (this.cursorFn = fn, this) let prev + , error = null return { [Symbol.asyncIterator]: () => ({ next: () => { + if (error) { + const err = error + error = null + return Promise.reject(err) + } if (this.executed && !this.active) return { done: true } @@ -97,7 +103,7 @@ export class Query extends Promise { return new Promise(r => prev = r) } this.resolve = () => (this.active = false, resolve({ done: true })) - this.reject = x => (this.active = false, reject(x)) + this.reject = x => (this.active = false, error = x, reject(x)) }) this.execute() return promise diff --git a/deno/tests/index.js b/deno/tests/index.js index cc2a2518..cd3c7b0e 100644 --- a/deno/tests/index.js +++ b/deno/tests/index.js @@ -1459,6 +1459,21 @@ t('Async Iterator Cursor custom with less results than batch size', async() => { return ['20', order.join(',')] }) +t('Async Iterator Cursor surfaces error arriving between batches', async() => { + const query = sql`select * from generate_series(1,5) as x` + const iterator = query.cursor(1)[Symbol.asyncIterator]() + await iterator.next() + query.reject(new Error('between-batch')) + let caught + try { + await iterator.next() + } catch (err) { + caught = err.message + } + await iterator.return() + return ['between-batch', caught] +}) + t('Transform row', async() => { const sql = postgres({ ...options, diff --git a/src/query.js b/src/query.js index 0d44a15c..02ad6f36 100644 --- a/src/query.js +++ b/src/query.js @@ -84,9 +84,15 @@ export class Query extends Promise { return (this.cursorFn = fn, this) let prev + , error = null return { [Symbol.asyncIterator]: () => ({ next: () => { + if (error) { + const err = error + error = null + return Promise.reject(err) + } if (this.executed && !this.active) return { done: true } @@ -97,7 +103,7 @@ export class Query extends Promise { return new Promise(r => prev = r) } this.resolve = () => (this.active = false, resolve({ done: true })) - this.reject = x => (this.active = false, reject(x)) + this.reject = x => (this.active = false, error = x, reject(x)) }) this.execute() return promise diff --git a/tests/index.js b/tests/index.js index 23e6c4d4..5161f28b 100644 --- a/tests/index.js +++ b/tests/index.js @@ -1457,6 +1457,21 @@ t('Async Iterator Cursor custom with less results than batch size', async() => { return ['20', order.join(',')] }) +t('Async Iterator Cursor surfaces error arriving between batches', async() => { + const query = sql`select * from generate_series(1,5) as x` + const iterator = query.cursor(1)[Symbol.asyncIterator]() + await iterator.next() + query.reject(new Error('between-batch')) + let caught + try { + await iterator.next() + } catch (err) { + caught = err.message + } + await iterator.return() + return ['between-batch', caught] +}) + t('Transform row', async() => { const sql = postgres({ ...options,