diff --git a/src/ext/hx-sse.js b/src/ext/hx-sse.js index 789a82c89..7f7106372 100644 --- a/src/ext/hx-sse.js +++ b/src/ext/hx-sse.js @@ -398,6 +398,10 @@ let releaseRequest; ctx.extensionPromise = new Promise(resolve => releaseRequest = resolve); handleSSEResponse(ctx, releaseRequest).catch(e => { + // a throw before the stream loop skips the finally, so release + // the request here and tear the connection down + releaseRequest(); + cleanup(element); // an aborted stream is a normal end, not an error if (e.name !== 'AbortError') { api.triggerHtmxEvent(element, 'htmx:sse:error', {error: e, url: ctx.request.action}); diff --git a/test/tests/ext/hx-sse.js b/test/tests/ext/hx-sse.js index 0e8be82a6..3b6d31f63 100644 --- a/test/tests/ext/hx-sse.js +++ b/test/tests/ext/hx-sse.js @@ -62,6 +62,30 @@ describe('hx-sse SSE extension', function() { stream.close(); }); + it('releases the request when setup throws', async function() { + mockStreamResponse('/setup-throw'); + createProcessedHTML('