Repository navigation
Description
An asynchronous contextDataFactory failure in @fedify/express becomes an unhandled rejection instead of reaching Express error-handling middleware. This matters when the factory loads context from a session or database: the application cannot send its normal error response.
Reproduction
With @fedify/express 2.4.1 and Express 5.2.1, run this as an .mjs file and request http://localhost:3000/:
import { integrateFederation } from "@fedify/express";
import express from "express";
import process from "node:process";
const app = express();
// A fetch-only mock isolates the adapter; this callback is never reached.
const federation = { async fetch() { return new Response("ok"); } };
app.use(integrateFederation(federation, async () => {
throw new Error("context failed");
}));
app.use((error, _req, res, _next) => {
res.status(500).send(error.message);
});
// Observe the rejection without letting it terminate the reproduction process.
process.on("unhandledRejection", (error) => {
console.error("unhandledRejection:", error.message);
});
app.listen(3000);Expected: the error reaches the error-handling middleware and the client receives 500 context failed.
Actual: unhandledRejection: context failed is logged, the error handler is not called, and the client receives no response. A request using a one-second AbortSignal.timeout() times out. A synchronous factory throwing the same error does reach the error handler and returns 500.
The same failure occurs if the factory resolves but the mock federation.fetch() rejects. Both cases reproduced on macOS 26.6.2 (arm64), with Node.js 22.23.1 and Deno 2.9.7, using Express 4.21.2 and 5.2.1. The successful-response control returned 200 in each run. It also reproduced on main at 3a7ba49033e5f12f89708c506b4d31a1bd0d969b on Deno with both Express versions.
In the adapter, contextDataPromise.then(...) has no rejection handler and the middleware does not return that promise. Express 5 therefore cannot forward the rejection automatically either. Could these asynchronous failures be forwarded to next(error), with regression tests for the factory and fetch rejection paths? #855 and #985 cover the resolved factory path.
This follows up on #855, as requested in this comment.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Effort
Activity
Forward asynchronous Express failures
dahlia commentedon Oct 8, 2026
Fixed in Fedify 2.0.32, 2.1.28, 2.2.17, 2.3.12, and 2.4.2.