fix(read-chunk): handle already errored streams
This commit is contained in:
@@ -18,7 +18,9 @@ const assert = require('assert')
|
||||
* @returns {Promise<Buffer|string|unknown|null>} - A Promise that resolves to the read chunk if available, or null if end of stream is reached.
|
||||
*/
|
||||
const readChunk = (stream, size) =>
|
||||
stream.closed || stream.readableEnded
|
||||
stream.errored != null
|
||||
? Promise.reject(stream.errored)
|
||||
: stream.closed || stream.readableEnded
|
||||
? Promise.resolve(null)
|
||||
: new Promise((resolve, reject) => {
|
||||
if (size !== undefined) {
|
||||
@@ -98,7 +100,9 @@ exports.readChunkStrict = async function readChunkStrict(stream, size) {
|
||||
* @returns {Promise<number>} A Promise that resolves to the number of bytes actually skipped. If the end of the stream is reached before all bytes are skipped, the Promise resolves to the number of bytes that were skipped before the end of the stream was reached. The Promise is rejected if there is an error while reading from the stream.
|
||||
*/
|
||||
async function skip(stream, size) {
|
||||
return size === 0 || stream.closed || stream.readableEnded
|
||||
return stream.errored != null
|
||||
? Promise.reject(stream.errored)
|
||||
: size === 0 || stream.closed || stream.readableEnded
|
||||
? Promise.resolve(0)
|
||||
: new Promise((resolve, reject) => {
|
||||
let left = size
|
||||
|
||||
@@ -18,6 +18,32 @@ const rejectionOf = promise =>
|
||||
error => error
|
||||
)
|
||||
|
||||
const makeErrorTests = fn => {
|
||||
it('rejects if the stream errors', async () => {
|
||||
const error = new Error()
|
||||
const stream = makeStream([])
|
||||
|
||||
const pError = rejectionOf(fn(stream, 10))
|
||||
stream.destroy(error)
|
||||
|
||||
assert.strict(await pError, error)
|
||||
})
|
||||
|
||||
// only supported for Node >= 18
|
||||
if (process.versions.node.split('.')[0] >= 18) {
|
||||
it('rejects if the stream has already errored', async () => {
|
||||
const error = new Error()
|
||||
const stream = makeStream([])
|
||||
|
||||
await new Promise(resolve => {
|
||||
stream.once('error', resolve).destroy(error)
|
||||
})
|
||||
|
||||
assert.strict(await rejectionOf(fn(stream, 10)), error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
describe('readChunk', () => {
|
||||
it('rejects if size is less than or equal to 0', async () => {
|
||||
const error = await rejectionOf(readChunk(makeStream([]), 0))
|
||||
@@ -29,6 +55,8 @@ describe('readChunk', () => {
|
||||
assert.strictEqual(error.code, 'ERR_ASSERTION')
|
||||
})
|
||||
|
||||
makeErrorTests(readChunk)
|
||||
|
||||
it('returns null if stream is empty', async () => {
|
||||
assert.strictEqual(await readChunk(makeStream([])), null)
|
||||
})
|
||||
@@ -83,6 +111,8 @@ describe('readChunkStrict', function () {
|
||||
})
|
||||
|
||||
describe('skip', function () {
|
||||
makeErrorTests(skip)
|
||||
|
||||
it('returns 0 if size is 0', async () => {
|
||||
assert.strictEqual(await skip(makeStream(['foo']), 0), 0)
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- [Plugins/usage-report] Compute stats on configured period instead of the whole year (PR [#6723](https://github.com/vatesfr/xen-orchestra/pull/6723))
|
||||
- [Backup] Fix `Invalid parameters` when deleting `speed limit` value (PR [#6768](https://github.com/vatesfr/xen-orchestra/pull/6768))
|
||||
- [Delta Backup] Restoring a backup with memory must create a suspended VM [#5061](https://github.com/vatesfr/xen-orchestra/issues/5061) (PR [#6774](https://github.com/vatesfr/xen-orchestra/pull/6774))
|
||||
- [Backup] Show original error instead of `stream has ended without data`
|
||||
|
||||
### Packages to release
|
||||
|
||||
@@ -33,6 +34,7 @@
|
||||
|
||||
<!--packages-start-->
|
||||
|
||||
- @vates/read-chunk patch
|
||||
- xo-web patch
|
||||
- xo-server minor
|
||||
- xo-server-usage-report patch
|
||||
|
||||
Reference in New Issue
Block a user