react-on-rails-pro-node-renderer 16.7.0-rc.2 → 16.7.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resetOpenTelemetryForTest = resetOpenTelemetryForTest;
37
+ const opentelemetryState_js_1 = require("../shared/opentelemetryState.js");
38
+ const tracing_js_1 = require("../shared/tracing.js");
39
+ const fastifyConfig = __importStar(require("../worker/fastifyConfig.js"));
40
+ const shutdownHooks = __importStar(require("../worker/shutdownHooks.js"));
41
+ async function resetOpenTelemetryForTest() {
42
+ const tracerProvider = (0, opentelemetryState_js_1.getOpenTelemetryTracerProvider)();
43
+ if (tracerProvider) {
44
+ await tracerProvider.shutdown();
45
+ (0, opentelemetryState_js_1.setOpenTelemetryTracerProvider)(null);
46
+ }
47
+ (0, tracing_js_1.resetSubSpan)();
48
+ (0, tracing_js_1.resetTracing)();
49
+ // eslint-disable-next-line no-underscore-dangle
50
+ fastifyConfig.__resetFastifyConfigFunctionsForTest();
51
+ // eslint-disable-next-line no-underscore-dangle
52
+ shutdownHooks.__resetWorkerShutdownHooksForTest();
53
+ /* eslint-disable @typescript-eslint/no-require-imports, global-require */
54
+ try {
55
+ const otelApi = require('@opentelemetry/api');
56
+ otelApi.trace.disable();
57
+ otelApi.context.disable();
58
+ otelApi.propagation.disable();
59
+ otelApi.diag.disable();
60
+ }
61
+ catch {
62
+ // OTel API not installed - nothing to disable.
63
+ }
64
+ /* eslint-enable @typescript-eslint/no-require-imports, global-require */
65
+ }
66
+ //# sourceMappingURL=opentelemetry.js.map
@@ -0,0 +1,19 @@
1
+ import type { FastifyInstance } from './types.js';
2
+ export type FastifyConfigFunction = (app: FastifyInstance) => void;
3
+ /**
4
+ * Configures the Fastify instance before starting the server.
5
+ *
6
+ * This module intentionally has no runtime dependency on `worker.ts` or
7
+ * `fastify`, so integrations can register instrumentation before Fastify is
8
+ * required by the worker module graph.
9
+ */
10
+ export declare function registerFastifyConfigFunction(configFunction: FastifyConfigFunction): () => void;
11
+ /**
12
+ * Public one-way registration API for custom entrypoints and integrations.
13
+ * Internal callers use registerFastifyConfigFunction() when they need the
14
+ * unregister callback during failed initialization or shutdown cleanup.
15
+ */
16
+ export declare function configureFastify(configFunction: FastifyConfigFunction): void;
17
+ export declare function applyFastifyConfigFunctions(app: FastifyInstance): void;
18
+ export declare function __resetFastifyConfigFunctionsForTest(): void;
19
+ //# sourceMappingURL=fastifyConfig.d.ts.map
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerFastifyConfigFunction = registerFastifyConfigFunction;
4
+ exports.configureFastify = configureFastify;
5
+ exports.applyFastifyConfigFunctions = applyFastifyConfigFunctions;
6
+ exports.__resetFastifyConfigFunctionsForTest = __resetFastifyConfigFunctionsForTest;
7
+ const fastifyConfigFunctions = [];
8
+ /**
9
+ * Configures the Fastify instance before starting the server.
10
+ *
11
+ * This module intentionally has no runtime dependency on `worker.ts` or
12
+ * `fastify`, so integrations can register instrumentation before Fastify is
13
+ * required by the worker module graph.
14
+ */
15
+ function registerFastifyConfigFunction(configFunction) {
16
+ fastifyConfigFunctions.push(configFunction);
17
+ return () => {
18
+ const index = fastifyConfigFunctions.indexOf(configFunction);
19
+ if (index >= 0) {
20
+ fastifyConfigFunctions.splice(index, 1);
21
+ }
22
+ };
23
+ }
24
+ /**
25
+ * Public one-way registration API for custom entrypoints and integrations.
26
+ * Internal callers use registerFastifyConfigFunction() when they need the
27
+ * unregister callback during failed initialization or shutdown cleanup.
28
+ */
29
+ function configureFastify(configFunction) {
30
+ registerFastifyConfigFunction(configFunction);
31
+ }
32
+ function applyFastifyConfigFunctions(app) {
33
+ fastifyConfigFunctions.forEach((configFunction) => {
34
+ configFunction(app);
35
+ });
36
+ }
37
+ // eslint-disable-next-line no-underscore-dangle
38
+ function __resetFastifyConfigFunctionsForTest() {
39
+ fastifyConfigFunctions.length = 0;
40
+ }
41
+ //# sourceMappingURL=fastifyConfig.js.map
@@ -6,6 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const cluster_1 = __importDefault(require("cluster"));
7
7
  const utils_js_1 = require("../shared/utils.js");
8
8
  const log_js_1 = __importDefault(require("../shared/log.js"));
9
+ const shutdownHooks_js_1 = require("./shutdownHooks.js");
10
+ function errorCode(error) {
11
+ const code = error?.code;
12
+ return typeof code === 'string' ? code : undefined;
13
+ }
9
14
  const handleGracefulShutdown = (app) => {
10
15
  const { worker } = cluster_1.default;
11
16
  if (!worker) {
@@ -14,12 +19,54 @@ const handleGracefulShutdown = (app) => {
14
19
  }
15
20
  let activeRequestsCount = 0;
16
21
  let isShuttingDown = false;
22
+ let isDestroying = false;
23
+ const destroyWorkerAfterShutdownHooks = (context) => {
24
+ if (isDestroying) {
25
+ return;
26
+ }
27
+ isDestroying = true;
28
+ log_js_1.default.debug('Worker #%d running shutdown hooks before shutdown after %s', worker.id, context);
29
+ let workerDestroyed = false;
30
+ const destroyWorker = () => {
31
+ if (workerDestroyed) {
32
+ return;
33
+ }
34
+ workerDestroyed = true;
35
+ worker.destroy();
36
+ };
37
+ const shutdownTimeout = setTimeout(() => {
38
+ log_js_1.default.warn('Worker #%d: shutdown hooks timed out, forcing worker.destroy()', worker.id);
39
+ destroyWorker();
40
+ }, shutdownHooks_js_1.WORKER_SHUTDOWN_HOOKS_TIMEOUT_MS);
41
+ const shutdownHooksPromise = (0, shutdownHooks_js_1.runWorkerShutdownHooks)();
42
+ void shutdownHooksPromise
43
+ .catch((error) => {
44
+ log_js_1.default.warn({ msg: 'Error running worker shutdown hooks before worker shutdown', error });
45
+ })
46
+ .finally(() => {
47
+ clearTimeout(shutdownTimeout);
48
+ destroyWorker();
49
+ });
50
+ };
51
+ const disconnectWorker = () => {
52
+ try {
53
+ worker.disconnect();
54
+ }
55
+ catch (error) {
56
+ if (errorCode(error) === 'ERR_IPC_DISCONNECTED') {
57
+ log_js_1.default.debug('Worker #%d IPC channel was already disconnected during graceful shutdown', worker.id);
58
+ }
59
+ else {
60
+ log_js_1.default.warn({ msg: 'Error disconnecting worker during graceful shutdown', error });
61
+ }
62
+ }
63
+ };
17
64
  // Helper to decrement counter and potentially kill worker
18
65
  const decrementAndMaybeShutdown = (context) => {
19
66
  activeRequestsCount -= 1;
20
67
  if (isShuttingDown && activeRequestsCount === 0) {
21
68
  log_js_1.default.debug('Worker #%d has no active requests after %s, killing the worker', worker.id, context);
22
- worker.destroy();
69
+ destroyWorkerAfterShutdownHooks(context);
23
70
  }
24
71
  };
25
72
  process.on('message', (msg) => {
@@ -28,11 +75,11 @@ const handleGracefulShutdown = (app) => {
28
75
  isShuttingDown = true;
29
76
  if (activeRequestsCount === 0) {
30
77
  log_js_1.default.debug('Worker #%d has no active requests, killing the worker', worker.id);
31
- worker.destroy();
78
+ destroyWorkerAfterShutdownHooks('shutdown message');
32
79
  }
33
80
  else {
34
81
  log_js_1.default.debug('Worker #%d has "%d" active requests, disconnecting the worker', worker.id, activeRequestsCount);
35
- worker.disconnect();
82
+ disconnectWorker();
36
83
  }
37
84
  }
38
85
  });
@@ -7,6 +7,13 @@ exports.handleIncrementalRenderRequest = handleIncrementalRenderRequest;
7
7
  const handleRenderRequest_1 = require("./handleRenderRequest");
8
8
  const log_1 = __importDefault(require("../shared/log"));
9
9
  const utils_1 = require("../shared/utils");
10
+ const tracing_js_1 = require("../shared/tracing.js");
11
+ class InvalidIncrementalRenderChunkError extends Error {
12
+ constructor() {
13
+ super('Invalid incremental render chunk received, missing properties');
14
+ this.name = 'InvalidIncrementalRenderChunkError';
15
+ }
16
+ }
10
17
  function assertIsUpdateChunk(value) {
11
18
  if (typeof value !== 'object' ||
12
19
  value === null ||
@@ -14,7 +21,7 @@ function assertIsUpdateChunk(value) {
14
21
  !('updateChunk' in value) ||
15
22
  (typeof value.bundleTimestamp !== 'string' && typeof value.bundleTimestamp !== 'number') ||
16
23
  typeof value.updateChunk !== 'string') {
17
- throw new Error('Invalid incremental render chunk received, missing properties');
24
+ throw new InvalidIncrementalRenderChunkError();
18
25
  }
19
26
  }
20
27
  function assertFirstIncrementalRenderRequestChunk(chunk) {
@@ -63,6 +70,8 @@ async function handleIncrementalRenderRequest(initial) {
63
70
  const { renderingRequest, onRequestClosedUpdateChunk } = firstRequestChunk;
64
71
  try {
65
72
  // Call handleRenderRequest internally to handle all validation and VM execution
73
+ // handleRenderRequest is called directly without a TracingContext from worker.ts's
74
+ // trace() wrapper, so there is no tracingContext to forward for its error path.
66
75
  const { response, executionContext } = await (0, handleRenderRequest_1.handleRenderRequest)({
67
76
  renderingRequest,
68
77
  bundleTimestamp,
@@ -82,13 +91,21 @@ async function handleIncrementalRenderRequest(initial) {
82
91
  add: async (chunk) => {
83
92
  try {
84
93
  assertIsUpdateChunk(chunk);
85
- const bundlePath = (0, utils_1.getRequestBundleFilePath)(chunk.bundleTimestamp);
86
- await executionContext.runInVM(chunk.updateChunk, bundlePath).catch((err) => {
87
- log_1.default.error({ msg: 'Error running incremental render chunk', err, chunk });
94
+ await (0, tracing_js_1.subSpan)({ name: 'ror.incremental.process_chunk' }, async () => {
95
+ const bundlePath = (0, utils_1.getRequestBundleFilePath)(chunk.bundleTimestamp);
96
+ const result = await executionContext.runInVM(chunk.updateChunk, bundlePath);
97
+ if ((0, utils_1.isErrorRenderResult)(result)) {
98
+ throw new Error(result.exceptionMessage);
99
+ }
88
100
  });
89
101
  }
90
102
  catch (err) {
91
- log_1.default.error({ msg: 'Invalid incremental render chunk', err, chunk });
103
+ if (err instanceof InvalidIncrementalRenderChunkError) {
104
+ log_1.default.error({ msg: 'Invalid incremental render chunk', err, chunk });
105
+ }
106
+ else {
107
+ log_1.default.error({ msg: 'Error running incremental render chunk', err, chunk });
108
+ }
92
109
  }
93
110
  },
94
111
  handleRequestClosed: () => {
@@ -38,6 +38,7 @@ exports.handleIncrementalRenderStream = handleIncrementalRenderStream;
38
38
  const string_decoder_1 = require("string_decoder");
39
39
  const errorReporter = __importStar(require("../shared/errorReporter"));
40
40
  const constants_1 = require("../shared/constants");
41
+ const tracing_js_1 = require("../shared/tracing.js");
41
42
  /**
42
43
  * Error thrown when waiting for a stream chunk times out.
43
44
  */
@@ -87,116 +88,118 @@ async function* withChunkTimeout(iterator, timeoutMs) {
87
88
  * The first object triggers rendering, subsequent objects provide incremental updates.
88
89
  */
89
90
  async function handleIncrementalRenderStream(options) {
90
- const { request, onRenderRequestReceived, onResponseStart, onUpdateReceived, onRequestEnded } = options;
91
- let hasReceivedFirstObject = false;
92
- const decoder = new string_decoder_1.StringDecoder('utf8');
93
- let buffer = '';
94
- let totalBytesReceived = 0;
95
- let onResponseStartPromise = null;
96
- try {
97
- for await (const chunk of withChunkTimeout(request.raw, constants_1.STREAM_CHUNK_TIMEOUT_MS)) {
98
- const chunkBuffer = chunk instanceof Buffer ? chunk : Buffer.from(chunk);
99
- totalBytesReceived += chunkBuffer.length;
100
- // Check total request size limit
101
- if (totalBytesReceived > constants_1.BODY_SIZE_LIMIT) {
102
- throw new Error(`NDJSON request exceeds maximum size of ${constants_1.BODY_SIZE_LIMIT} bytes (${Math.round(constants_1.BODY_SIZE_LIMIT / 1024 / 1024)}MB). ` +
103
- `Received ${totalBytesReceived} bytes.`);
104
- }
105
- const str = decoder.write(chunkBuffer);
106
- buffer += str;
107
- // Check single line size limit (protects against missing newlines)
108
- if (buffer.length > constants_1.FIELD_SIZE_LIMIT) {
109
- throw new Error(`NDJSON line exceeds maximum size of ${constants_1.FIELD_SIZE_LIMIT} bytes (${Math.round(constants_1.FIELD_SIZE_LIMIT / 1024 / 1024)}MB). ` +
110
- `Current buffer: ${buffer.length} bytes. Ensure each JSON object is followed by a newline.`);
111
- }
112
- // Process all complete JSON objects in the buffer
113
- let boundary = buffer.indexOf('\n');
114
- while (boundary !== -1) {
115
- const rawObject = buffer.slice(0, boundary).trim();
116
- buffer = buffer.slice(boundary + 1);
117
- boundary = buffer.indexOf('\n');
118
- if (rawObject) {
119
- let parsed;
120
- try {
121
- parsed = JSON.parse(rawObject);
122
- }
123
- catch (err) {
124
- const errorMessage = `Invalid JSON chunk: ${err instanceof Error ? err.message : String(err)}`;
125
- if (!hasReceivedFirstObject) {
126
- // Error in first chunk - throw error to stop processing
127
- throw new Error(errorMessage);
128
- }
129
- else {
130
- // Error in subsequent chunks - log and report but continue processing
131
- const reportedMessage = `JSON parsing error in update chunk: ${err instanceof Error ? err.message : String(err)}`;
132
- errorReporter.message(reportedMessage);
133
- // Skip this malformed chunk and continue with next ones
134
- // eslint-disable-next-line no-continue
135
- continue;
136
- }
137
- }
138
- if (!hasReceivedFirstObject) {
139
- hasReceivedFirstObject = true;
91
+ return (0, tracing_js_1.subSpan)({ name: 'ror.incremental.stream' }, async () => {
92
+ const { request, onRenderRequestReceived, onResponseStart, onUpdateReceived, onRequestEnded } = options;
93
+ let hasReceivedFirstObject = false;
94
+ const decoder = new string_decoder_1.StringDecoder('utf8');
95
+ let buffer = '';
96
+ let totalBytesReceived = 0;
97
+ let onResponseStartPromise = null;
98
+ try {
99
+ for await (const chunk of withChunkTimeout(request.raw, constants_1.STREAM_CHUNK_TIMEOUT_MS)) {
100
+ const chunkBuffer = chunk instanceof Buffer ? chunk : Buffer.from(chunk);
101
+ totalBytesReceived += chunkBuffer.length;
102
+ // Check total request size limit
103
+ if (totalBytesReceived > constants_1.BODY_SIZE_LIMIT) {
104
+ throw new Error(`NDJSON request exceeds maximum size of ${constants_1.BODY_SIZE_LIMIT} bytes (${Math.round(constants_1.BODY_SIZE_LIMIT / 1024 / 1024)}MB). ` +
105
+ `Received ${totalBytesReceived} bytes.`);
106
+ }
107
+ const str = decoder.write(chunkBuffer);
108
+ buffer += str;
109
+ // Check single line size limit (protects against missing newlines)
110
+ if (buffer.length > constants_1.FIELD_SIZE_LIMIT) {
111
+ throw new Error(`NDJSON line exceeds maximum size of ${constants_1.FIELD_SIZE_LIMIT} bytes (${Math.round(constants_1.FIELD_SIZE_LIMIT / 1024 / 1024)}MB). ` +
112
+ `Current buffer: ${buffer.length} bytes. Ensure each JSON object is followed by a newline.`);
113
+ }
114
+ // Process all complete JSON objects in the buffer
115
+ let boundary = buffer.indexOf('\n');
116
+ while (boundary !== -1) {
117
+ const rawObject = buffer.slice(0, boundary).trim();
118
+ buffer = buffer.slice(boundary + 1);
119
+ boundary = buffer.indexOf('\n');
120
+ if (rawObject) {
121
+ let parsed;
140
122
  try {
141
- // eslint-disable-next-line no-await-in-loop
142
- const result = await onRenderRequestReceived(parsed);
143
- const { response, shouldContinue: continueFlag } = result;
144
- onResponseStartPromise = Promise.resolve(onResponseStart(response));
145
- if (!continueFlag) {
146
- return;
147
- }
123
+ parsed = JSON.parse(rawObject);
148
124
  }
149
125
  catch (err) {
150
- // Error in first chunk processing - throw error to stop processing
151
- const error = err instanceof Error ? err : new Error(String(err));
152
- error.message = `Error processing initial render request: ${error.message}`;
153
- throw error;
126
+ const errorMessage = `Invalid JSON chunk: ${err instanceof Error ? err.message : String(err)}`;
127
+ if (!hasReceivedFirstObject) {
128
+ // Error in first chunk - throw error to stop processing
129
+ throw new Error(errorMessage);
130
+ }
131
+ else {
132
+ // Error in subsequent chunks - log and report but continue processing
133
+ const reportedMessage = `JSON parsing error in update chunk: ${err instanceof Error ? err.message : String(err)}`;
134
+ errorReporter.message(reportedMessage);
135
+ // Skip this malformed chunk and continue with next ones
136
+ // eslint-disable-next-line no-continue
137
+ continue;
138
+ }
154
139
  }
155
- }
156
- else {
157
- try {
158
- // eslint-disable-next-line no-await-in-loop
159
- await onUpdateReceived(parsed);
160
- // Yield to the event loop after each update chunk so React's
161
- // setImmediate(performWork) can fire. Without this, all setProp()
162
- // calls batch into React's pingedTasks and are processed in a
163
- // single performWork → single flushCompletedQueues, merging all
164
- // resolved Suspense boundaries into one chunk.
165
- // With this yield, each setProp triggers its own performWork →
166
- // flushCompletedQueues → destination.flush(), producing a
167
- // separate output chunk per resolved Suspense boundary.
168
- //
169
- // Tradeoff: adds one event-loop tick (~0.1ms) per update chunk.
170
- // For N async props this costs N extra ticks, but the streaming
171
- // granularity gain far outweighs it (see PR #3196 benchmarks).
172
- //
173
- // Note: on the error path (catch block below), the yield is
174
- // skipped — intentional, as there's no React work to process
175
- // when the update failed.
176
- // eslint-disable-next-line no-await-in-loop
177
- await new Promise((resolve) => {
178
- setImmediate(resolve);
179
- });
140
+ if (!hasReceivedFirstObject) {
141
+ hasReceivedFirstObject = true;
142
+ try {
143
+ // eslint-disable-next-line no-await-in-loop
144
+ const result = await onRenderRequestReceived(parsed);
145
+ const { response, shouldContinue: continueFlag } = result;
146
+ onResponseStartPromise = Promise.resolve(onResponseStart(response));
147
+ if (!continueFlag) {
148
+ return;
149
+ }
150
+ }
151
+ catch (err) {
152
+ // Error in first chunk processing - throw error to stop processing
153
+ const error = err instanceof Error ? err : new Error(String(err));
154
+ error.message = `Error processing initial render request: ${error.message}`;
155
+ throw error;
156
+ }
180
157
  }
181
- catch (err) {
182
- // Error in update chunk processing - log and report but continue processing
183
- const errorMessage = `Error processing update chunk: ${err instanceof Error ? err.message : String(err)}`;
184
- errorReporter.message(errorMessage);
185
- // Continue processing other chunks
158
+ else {
159
+ try {
160
+ // eslint-disable-next-line no-await-in-loop
161
+ await onUpdateReceived(parsed);
162
+ // Yield to the event loop after each update chunk so React's
163
+ // setImmediate(performWork) can fire. Without this, all setProp()
164
+ // calls batch into React's pingedTasks and are processed in a
165
+ // single performWork → single flushCompletedQueues, merging all
166
+ // resolved Suspense boundaries into one chunk.
167
+ // With this yield, each setProp triggers its own performWork →
168
+ // flushCompletedQueues → destination.flush(), producing a
169
+ // separate output chunk per resolved Suspense boundary.
170
+ //
171
+ // Tradeoff: adds one event-loop tick (~0.1ms) per update chunk.
172
+ // For N async props this costs N extra ticks, but the streaming
173
+ // granularity gain far outweighs it (see PR #3196 benchmarks).
174
+ //
175
+ // Note: on the error path (catch block below), the yield is
176
+ // skipped — intentional, as there's no React work to process
177
+ // when the update failed.
178
+ // eslint-disable-next-line no-await-in-loop
179
+ await new Promise((resolve) => {
180
+ setImmediate(resolve);
181
+ });
182
+ }
183
+ catch (err) {
184
+ // Error in update chunk processing - log and report but continue processing
185
+ const errorMessage = `Error processing update chunk: ${err instanceof Error ? err.message : String(err)}`;
186
+ errorReporter.message(errorMessage);
187
+ // Continue processing other chunks
188
+ }
186
189
  }
187
190
  }
188
191
  }
189
192
  }
190
193
  }
191
- }
192
- catch (err) {
193
- const error = err instanceof Error ? err : new Error(String(err));
194
- // Update the error message in place to retain the original stack trace, rather than creating a new error object
195
- error.message = `Error while handling the request stream: ${error.message}`;
196
- throw error;
197
- }
198
- // Stream ended normally
199
- await onRequestEnded();
200
- await onResponseStartPromise;
194
+ catch (err) {
195
+ const error = err instanceof Error ? err : new Error(String(err));
196
+ // Update the error message in place to retain the original stack trace, rather than creating a new error object
197
+ error.message = `Error while handling the request stream: ${error.message}`;
198
+ throw error;
199
+ }
200
+ // Stream ended normally
201
+ await onRequestEnded();
202
+ await onResponseStartPromise;
203
+ });
201
204
  }
202
205
  //# sourceMappingURL=handleIncrementalRenderStream.js.map
@@ -5,8 +5,9 @@
5
5
  * @module worker/handleRenderRequest
6
6
  */
7
7
  import { Asset, ResponseResult, type RequestInfo } from '../shared/utils.js';
8
- import type { TracingContext } from '../shared/tracing.js';
8
+ import { type TracingContext } from '../shared/tracing.js';
9
9
  import { ExecutionContext } from './vm.js';
10
+ export declare function sumUploadedBytes(assets: Asset[]): Promise<number>;
10
11
  export type ProvidedNewBundle = {
11
12
  timestamp: string | number;
12
13
  bundle: Asset;