When passing a stream as an attachment to db.attachments.insert(...), nano should stream the contents to the database regardless of the stream's implementation details.
Current Behavior
Nano uses a "poor man's deep clone" to create a copy of the request data (added in #256) before scrubbing the username and password for logging. When using a custom stream, this can create an issue where you are serializing a stream, which contains lots of circular references, and cannot be done.
You don't need to clone the entire object. Deep cloning uses a lot of computing power for something that probably won't even end up happening. If you do a shallow clone, you can then omit the entire auth property (which might be safer if there is other authentication data in it). Data won't be modified during logging, so pass-by-reference (the issue deep cloning solves) shouldn't be an issue here.
Steps to Reproduce (for bugs)
Create a readable stream (ex: const myStream = fs.createReadStream(...))
Create a circular reference (ex: myStream.test = myStream) (many stream implementations have these for a variety of reasons).
Pass the req object into db.attachments.insert(...) as the data
A circular reference error is emitted from JSON.stringify(...)
Context
I am trying to stream an upload via ExpressJS into CouchDB and need to either patch nano or use a PassThrough stream to omit circular references being passed to CouchDB. JSON.stringify() in most cases should not be used on objects that contain classes, because a great number of class implementations contain circular references.
Your Environment
Version used: 9.0.3
Browser Name and version: N/A
Operating System and version (desktop or mobile): 11.4
Thanks @sploders101. You reasoning is very sensible: i've never liked JSON.parse(JSON.stringify(x)) and you're right than in this case it's cloning too much data.
Expected Behavior
When passing a stream as an attachment to
db.attachments.insert(...)
, nano should stream the contents to the database regardless of the stream's implementation details.Current Behavior
Nano uses a "poor man's deep clone" to create a copy of the request data (added in #256) before scrubbing the username and password for logging. When using a custom stream, this can create an issue where you are serializing a stream, which contains lots of circular references, and cannot be done.
Possible Solution
Implement a better scrubbing strategy. Ex:
You don't need to clone the entire object. Deep cloning uses a lot of computing power for something that probably won't even end up happening. If you do a shallow clone, you can then omit the entire auth property (which might be safer if there is other authentication data in it). Data won't be modified during logging, so pass-by-reference (the issue deep cloning solves) shouldn't be an issue here.
Steps to Reproduce (for bugs)
const myStream = fs.createReadStream(...)
)myStream.test = myStream
) (many stream implementations have these for a variety of reasons).db.attachments.insert(...)
as the dataContext
I am trying to stream an upload via ExpressJS into CouchDB and need to either patch nano or use a
PassThrough
stream to omit circular references being passed to CouchDB.JSON.stringify()
in most cases should not be used on objects that contain classes, because a great number of class implementations contain circular references.Your Environment