nodejs / nodejs/undici

Cache interceptor failing with "invalid onError method"

Open
#3,973 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
JavaScript
Stars
7.7k
Forks
880
Avg merge
2d 16h
Merged PRs (30d)
68

Description

Bug Description

I'm trying to make use of Undici 7's new caching feature but I'm getting this error when trying to follow the example provided in the announcement blog post: https://blog.platformatic.dev/undici-v7-is-here#heading-caching

node:internal/deps/undici/undici:591
            throw new InvalidArgumentError("invalid onError method");
                  ^

InvalidArgumentError: invalid onError method
    at Agent.dispatch (node:internal/deps/undici/undici:591:19)
    at handleUncachedResponse (/private/tmp/undici-test/node_modules/undici/lib/interceptor/cache.js:102:10)
    at handleResult (/private/tmp/undici-test/node_modules/undici/lib/interceptor/cache.js:205:12)
    at ComposedDispatcher.<anonymous> (/private/tmp/undici-test/node_modules/undici/lib/interceptor/cache.js:348:9)
    at ComposedDispatcher.dispatch (node:internal/deps/undici/undici:425:23)
    at ComposedDispatcher.request (/private/tmp/undici-test/node_modules/undici/lib/api/api-request.js:188:10)
    at /private/tmp/undici-test/node_modules/undici/lib/api/api-request.js:179:15
    at new Promise (<anonymous>)
    at ComposedDispatcher.request (/private/tmp/undici-test/node_modules/undici/lib/api/api-request.js:178:12)
    at /private/tmp/undici-test/node_modules/undici/index.js:102:15 {
  code: 'UND_ERR_INVALID_ARG'
}

Reproducible By

import { setGlobalDispatcher, getGlobalDispatcher, interceptors, request } from 'undici'
import {createServer} from "node:http"

/* Create simple http server that returns timestamp */
const server = createServer((req, res) => {
  res.setHeader('Cache-Control', 'public, max-age=604800, immutable');
  // res.setHeader('Cache-Control', 'no-store');
  res.end(Date.now().toString())
}).listen(0)
const address = server.address()
if (!address || typeof address === "string") {
  throw Error("Failed to start server")
}
const url = `http://localhost:${address.port}`

/* Set global dispatcher to use caching */
setGlobalDispatcher(getGlobalDispatcher().compose(
  interceptors.cache())
)

let res

res = await request(url)
console.log(await res.text(), {cache: "force-cache"})

res = await fetch(url)
// This should be cached and thus return the same timestamp as the previous request
console.log(await res.text(), {cache: "force-cache"})

I'm using Node.js v23.4.0 (and also tried v23.5.0 with the same result) on macOS Sonoma 14.5. I've tried undici version 7.2.0, 7.1.1, 7.1.0 and 7.0.0.

Expected Behavior

No error to be thrown and the same response body to be printed for both requests.

Additional context

I also tried this example using the SqliteCacheStore but get the same error message. Although it did create a "cache.db" file.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied JavaScript reproduction on Node.js and trace the failing path in lib/interceptor/cache.js, especially handleUncachedResponse at line 102 and handleResult at line 205. Compare the composed cache dispatcher with the request flow shown in the stack trace. Done means the example completes without InvalidArgumentError and both requests print the same response body.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.