diff --git a/runtime/fastly/builtins/html-rewriter.cpp b/runtime/fastly/builtins/html-rewriter.cpp
index 7404a088f5..120358ea7c 100644
--- a/runtime/fastly/builtins/html-rewriter.cpp
+++ b/runtime/fastly/builtins/html-rewriter.cpp
@@ -353,7 +353,10 @@ bool HTMLRewritingStream::onElement(JSContext *cx, unsigned argc, JS::Value *vp)
struct OutputContextData {
JSContext *cx;
- JSObject *self;
+ JS::Heap self;
+ bool enqueue_failed;
+
+ OutputContextData(JSContext *cx, JSObject *self) : cx(cx), self(self), enqueue_failed(false) {}
};
void HTMLRewritingStream::finalize(JS::GCContext *gcx, JSObject *self) {
@@ -387,7 +390,7 @@ void HTMLRewritingStream::finalize(JS::GCContext *gcx, JSObject *self) {
static void output_callback(const char *chunk, size_t chunk_len, void *user_data) {
auto *ctx = static_cast(user_data);
JSContext *cx = ctx->cx;
- JSObject *self = ctx->self;
+ JS::RootedObject self(cx, ctx->self);
JS::RootedObject out_obj(cx, JS_NewUint8Array(cx, chunk_len));
if (!out_obj) {
@@ -405,6 +408,7 @@ static void output_callback(const char *chunk, size_t chunk_len, void *user_data
JS::RootedValue out_chunk(cx, JS::ObjectValue(*out_obj));
if (!TransformStreamDefaultController::Enqueue(cx, controller, out_chunk)) {
+ ctx->enqueue_failed = true;
return;
}
}
@@ -468,6 +472,13 @@ bool HTMLRewritingStream::transformAlgorithm(JSContext *cx, unsigned argc, JS::V
return false;
}
+ auto output_context = static_cast(
+ JS::GetReservedSlot(self, HTMLRewritingStream::Slots::OutputContext).toPrivate());
+ if (output_context->enqueue_failed) {
+ JS_ReportErrorASCII(cx, "Error processing HTML: output stream enqueue failed");
+ return false;
+ }
+
args.rval().setUndefined();
return true;
}