Skip to content

fix: abort the connection when a handler throws after the response started - #493

Open
RaphaelFakhri wants to merge 1 commit into
vercel:mainfrom
RaphaelFakhri:fix-send-error-headers-sent
Open

RaphaelFakhri wants to merge 1 commit into
vercel:mainfrom
RaphaelFakhri:fix-send-error-headers-sent

Conversation

@RaphaelFakhri

Copy link
Copy Markdown

Fixes an unhandled promise rejection when a handler throws after it has already started writing the response.

Problem

sendError() always calls send(), which sets Content-Length. If the handler already called res.write(), the headers are sent and setHeader() throws ERR_HTTP_HEADERS_SENT. The throw happens inside the catch of run(), so the promise from run() rejects with nothing to handle it. On current Node.js versions an unhandled rejection terminates the process.

module.exports = (req, res) => {
  res.write('partial');
  throw new Error('failed midway');
};

Changes

  • sendError() checks res.headersSent. When the headers are already sent, it can't send an error response, so it destroys the connection unless the response has ended. The client sees a failed request instead of a truncated body that looks complete.
  • Adds a test that throws after res.write() and asserts that run() resolves.

Testing

cd test && npx tap --ts suite/

Before the change, the new test fails with ERR_HTTP_HEADERS_SENT reported as an unhandled rejection. After the change, all three suites pass.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant