// index.js
'use strict'
if (process.env.VCR_MODE) {
const replayer = require('replayer')
replayer.configure({
headerWhitelist: [
// excludes User-Agent & Connection
'Content-Type', 'Accept-Encoding', 'Accept',
],
includeHeaderValues: true,
touchHits: false,
})
replayer.fixtureDir(__dirname)
}
const createFetch = require('fetch-ponyfill')
const Promise = require('pinkie-promise')
const {fetch} = createFetch({Promise})
;(async () => {
// some regular HTTP server responding with an HTML page.
const res = await fetch('http://192.168.12.100/')
if (!res.ok) throw new Error(res.statusText)
const body = await res.json()
console.log(body)
})()
.catch((err) => {
console.error(err)
process.exit(1)
})
expected behavior
With Node.js v16, it works as expected:
nvm use v16
# Now using Node v16.15.0 (npm 8.5.5) ~/.local/share/nvm/v16.15.0/bin/node
env VCR_MODE=record node index.js
# <!DOCTYPE
ls -lh
# …
# -rw-r--r-- 1 j staff 5.4K May 9 15:42 5927068e5c32e04a0b4a984873cca003
# -rw-r--r-- 1 j staff 718B May 9 15:42 5927068e5c32e04a0b4a984873cca003.headers
# …
env VCR_MODE=playback node index.js
# <!DOCTYPE
actual behavior
With Node.js v18, neither recording nor replaying works:
rm 5927068e5c32e04a0b4a984873cca003*
nvm use system
# Now using Node v18.0.0 (npm 8.6.0) /opt/homebrew/Cellar/node/18.0.0/bin/node
env VCR_MODE=record node index.js
# node:events:505
# throw er; // Unhandled 'error' event
# ^
# TypeError [ERR_INVALID_ARG_TYPE]: The "stream" argument must be an instance of Stream. Received an instance of EventEmitter
# at new NodeError (node:internal/errors:372:5)
# at eos (node:internal/streams/end-of-stream:62:11)
# at IncomingMessage._destroy (node:_http_incoming:189:21)
# at _destroy (node:internal/streams/destroy:109:10)
# at IncomingMessage.destroy (node:internal/streams/destroy:71:5)
# at endReadableNT (node:internal/streams/readable:1360:16)
# at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
# Emitted 'error' event on IncomingMessage instance at:
# at emitErrorNT (node:internal/streams/destroy:151:8)
# at emitErrorCloseNT (node:internal/streams/destroy:116:3)
# at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
# code: 'ERR_INVALID_ARG_TYPE'
# }
# Node.js v18.0.0
ls -lh
# …
# -rw-r--r-- 1 j staff 5.4K May 9 15:44 5927068e5c32e04a0b4a984873cca003
# -rw-r--r-- 1 j staff 718B May 9 15:44 5927068e5c32e04a0b4a984873cca003.headers
# …
env VCR_MODE=playback node index.js
# node:events:505
# throw er; // Unhandled 'error' event
# ^
# TypeError [ERR_INVALID_ARG_TYPE]: The "stream" argument must be an instance of Stream. Received an instance of EventEmitter
# at new NodeError (node:internal/errors:372:5)
# at eos (node:internal/streams/end-of-stream:62:11)
# at IncomingMessage._destroy (node:_http_incoming:189:21)
# at _destroy (node:internal/streams/destroy:109:10)
# at IncomingMessage.destroy (node:internal/streams/destroy:71:5)
# at endReadableNT (node:internal/streams/readable:1360:16)
# at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
# Emitted 'error' event on IncomingMessage instance at:
# at emitErrorNT (node:internal/streams/destroy:151:8)
# at emitErrorCloseNT (node:internal/streams/destroy:116:3)
# at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
# code: 'ERR_INVALID_ARG_TYPE'
# }
# Node.js v18.0.0
more info
It seems that it fails because node-fetch calls res.pipe(new PassThrough()):
Hi - sorry for the trouble. I am no longer maintaining this project. You might want to try out something like Polly.js: https://netflix.github.io/pollyjs/#/
setup
expected behavior
With Node.js v16, it works as expected:
actual behavior
With Node.js v18, neither recording nor replaying works:
more info
It seems that it fails because
node-fetch
callsres.pipe(new PassThrough())
: