apache / apache/couchdb-nano

db.attachment.getAsStream method does not propagate axios errors to the caller

Open
#236 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
689
Forks
167
Avg merge
1h
Merged PRs (30d)
1

Description

## Expected Behavior
If I call db.attachment.getAsStream() method and an axios error is thrown the caller should be notified.

## Current Behavior
If I call e.g. db.attachment.getAsStream() with a non-existing document id, axios throws an error (404)
The PassThrough instance that db.attachment.getAsStream() returns won't emit any events, so the caller
will never receive the error, an unhandledPromiseRejection warning is raised instead.

## Possible Solution
In case of an underlying axios error, the returned PassThrough instance should emit an `error` event.

I inspected the corresponding code, nano.js line 343: https://github.com/apache/couchdb-nano/blob/b3f33b64d75bcd59f8cd9d2b9cd1f90d104b7e94/lib/nano.js#L343
There should be a catch branch.

## Steps to Reproduce (for bugs)
```javascript
const couchUrl = 'http://admin:admin@localhost:5984'
const nano = require('nano')(couchUrl)
const dbName = 'mydb'
const db = nano.use(dbName)
async function run () {
console.log('start')
await nano.db.destroy(dbName)
console.log('db destroyed')
await nano.db.create(dbName)
console.log('db created')

const docId = 'abc1234'
const doc = { _id: docId, something: 'a' }
const data = 'some attachment'
const { rev } = await db.insert(doc)
const attName = 'attName'
console.log('inserting attachment')
const response = await db.attachment.insert(docId, attName, Buffer.from(data, 'utf-8'), 'text/plain', { rev })
console.log('attachment inserted', response)

const attStream = await db.attachment.getAsStream(docId, attName)
console.log('attachment stream returned')
await new Promise((resolve, reject) => {
attStream.on('data', () => console.log('data received:', data))
attStream.on('end', resolve)
attStream.on('error', reject)
})
console.log('attachment read OK')
try {
console.log('try reading attachment of a non-existing doc...')
const attStream2 = await db.attachment.getAsStream('fake_doc_id', attName)
console.log('attachment stream returned')
await new Promise((resolve, reject) => {
attStream2.on('data', () => console.log('data received: ', data))
attStream2.on('end', resolve)
attStream2.on('error', reject)
})
} catch (e) {
console.log('error', e.message)
}
}

run()
```
## Context
I am trying to create an internal API for reading and writing documents and their attachments.

## Your Environment
* Version used: 9.0.1
* Browser Name and version: -
* Operating System and version (desktop or mobile): macOS 10.15.7
* Link to your project:

Contributor guide

Open the contributing guide

Research direction

Start at lib/nano.js around line 343, where db.attachment.getAsStream() creates and returns the PassThrough stream. Run the provided reproduction against a missing document and verify that the returned stream emits the underlying axios error, allowing the caller's error handler to receive it instead of producing an unhandled promise rejection.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.