klaemo opened a new issue, #377:
URL: https://github.com/apache/couchdb-nano/issues/377

   ## Expected Behavior
   
   A query option whose value is `undefined` is left out of the request URL, as 
nano 10 did. For example, `db.view('ddoc', 'view', { limit: undefined, 
include_docs: true })` should request 
`/_design/ddoc/_view/view?include_docs=true`.
   
   ## Current Behavior
   
   Since the switch from axios to `fetch` in 11.0.0 (#314), `relax()` builds 
the query string with `new URLSearchParams(qs)`. `URLSearchParams` turns 
`undefined` into the string `"undefined"`, so the option is sent as 
`key=undefined`. For `startkey`/`endkey`/`key`/`keys`/`start_key`/`end_key` the 
same thing happens one step earlier: `JSON.stringify(undefined)` returns 
`undefined`, which is then serialised the same way.
   
   Requests that fail against CouchDB 3.3.3 with nano 11.0.7 (and current 
`main`, 53dea92):
   
   | call | request | CouchDB response |
   | --- | --- | --- |
   | `db.view('guests', 'by-email', { keys, limit: undefined, include_docs: 
true })` | `POST …/_view/by-email?limit=undefined&include_docs=true` | `400 
query_parse_error: Invalid value for integer: "undefined"` |
   | `db.view(ddoc, view, { start_key: undefined, end_key: undefined, group: 
true })` | `GET …?start_key=undefined&end_key=undefined&group=true` | `400 
bad_request: invalid UTF-8 JSON` |
   | `db.view(ddoc, view, { keys: undefined, reduce: false })` | `GET 
…?keys=undefined&reduce=false` (`keys` is falsy, so `view()` doesn't move it to 
a POST body) | rejected: `keys=undefined` isn't valid JSON |
   
   nano 10 serialised `params` with the `qs` library (`paramsSerializer`), 
which skips `undefined` values, so the same code worked there. Request bodies 
aren't affected: `JSON.stringify` already drops `undefined`, so `db.search`, 
`db.find` and the `keys`/`queries` POST bodies behave correctly.
   
   ## Possible Solution
   
   In `relax()`, after the JSON-encoding loop for the key parameters, delete 
any `qs` entry whose value is `undefined`. That covers every API that passes 
`qs` through `relax()`, not just views.
   
   I'd leave `null` alone. `startkey: null` is a valid CouchDB key and is 
correctly sent as `startkey=null` after JSON encoding. For other parameters 
`null` is an explicit value from the caller, and nano 10 didn't drop it either 
(`qs` serialised it as `key=`).
   
   I'm happy to send a PR with tests.
   
   ## Steps to Reproduce (for bugs)
   
   1. `npm install [email protected]`
   2. Run against any CouchDB 3.x database with a design document `ddoc` 
containing a map view `view`:
      ```js
      const nano = require('nano')('http://admin:[email protected]:5984')
      const db = nano.db.use('mydb')
      await db.view('ddoc', 'view', { limit: undefined, include_docs: true })
      ```
   3. The request is `GET 
/mydb/_design/ddoc/_view/view?limit=undefined&include_docs=true`. You can see 
it in CouchDB's request log or through a proxy. nano's own debug log omits the 
query string.
   4. CouchDB rejects it with `400 query_parse_error: Invalid value for 
integer: "undefined"`.
   
   ## Context
   
   We hit this while upgrading an app from nano 10.1.4 to 11.0.7. Passing 
optional values straight through, e.g. `{ limit: opts.limit, keys: opts.keys 
}`, is a common pattern that worked with nano 10. With nano 11 every caller has 
to strip `undefined` values itself. The migration guide doesn't mention this, 
and it fails at runtime with 400s rather than at compile time.
   
   ## Your Environment
   
   * Version used: nano 11.0.7 (also reproduced on `main` at 53dea92); CouchDB 
3.3.3
   * Browser Name and version: n/a (Node.js 24.21.0)
   * Operating System and version (desktop or mobile): Linux (Ubuntu, kernel 
6.8)
   * Link to your project: https://github.com/klaemo/guestlist (upgrade PR: 
https://github.com/klaemo/guestlist/pull/118)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to