Skip to content

@fedify/express does not forward asynchronous failures to next(error) #1244

Closed

Description

@ojspp41

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.

Activity

  1. added theissue type on Oct 5, 2026
  2. self-assigned this
    on Oct 6, 2026
  3. added a commit that references this issue on Oct 6, 2026
  4. dahlia commented on Oct 8, 2026

    @dahlia
    Member

    Fixed in Fedify 2.0.32, 2.1.28, 2.2.17, 2.3.12, and 2.4.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Fields

Priority

None yet

Effort

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions