@@ -27,6 +27,21 @@ const SANDBOX_BUNDLE_FILES = {
2727const bundleSourceCache = new Map ( )
2828const activeIsolates = new Map ( )
2929
30+ /**
31+ * Sends an IPC request and reports only actual delivery failures.
32+ * Node queues messages under backpressure, so the boolean return value is not
33+ * a failure signal.
34+ */
35+ function sendIpcRequest ( message , onError ) {
36+ try {
37+ process . send ( message , ( err ) => {
38+ if ( err ) onError ( err )
39+ } )
40+ } catch ( error ) {
41+ onError ( error instanceof Error ? error : new Error ( String ( error ) ) )
42+ }
43+ }
44+
3045function getBundleSource ( bundleName ) {
3146 const cached = bundleSourceCache . get ( bundleName )
3247 if ( cached ) return cached
@@ -233,13 +248,19 @@ async function executeCode(request, executionId) {
233248 }
234249 } , FETCH_TIMEOUT_MS )
235250 pendingFetches . set ( fetchId , { resolve, timeout } )
236- if ( process . send && process . connected ) {
237- process . send ( { type : 'fetch' , fetchId, requestId, url, optionsJson } )
238- } else {
251+ if ( ! process . send || ! process . connected ) {
239252 clearTimeout ( timeout )
240253 pendingFetches . delete ( fetchId )
241254 resolve ( JSON . stringify ( { error : 'Parent process disconnected' } ) )
255+ return
242256 }
257+ sendIpcRequest ( { type : 'fetch' , fetchId, requestId, url, optionsJson } , ( err ) => {
258+ const pending = pendingFetches . get ( fetchId )
259+ if ( ! pending ) return
260+ clearTimeout ( pending . timeout )
261+ pendingFetches . delete ( fetchId )
262+ pending . resolve ( JSON . stringify ( { error : `Fetch IPC send failed: ${ err . message } ` } ) )
263+ } )
243264 } )
244265 } )
245266 await jail . set ( '__fetchRef' , fetchCallback )
@@ -254,13 +275,19 @@ async function executeCode(request, executionId) {
254275 }
255276 } , BROKER_TIMEOUT_MS )
256277 pendingBrokerCalls . set ( brokerId , { resolve, timeout, executionId } )
257- if ( process . send && process . connected ) {
258- process . send ( { type : 'broker' , brokerId, executionId, brokerName, argsJson } )
259- } else {
278+ if ( ! process . send || ! process . connected ) {
260279 clearTimeout ( timeout )
261280 pendingBrokerCalls . delete ( brokerId )
262281 resolve ( JSON . stringify ( { error : 'Parent process disconnected' } ) )
282+ return
263283 }
284+ sendIpcRequest ( { type : 'broker' , brokerId, executionId, brokerName, argsJson } , ( err ) => {
285+ const pending = pendingBrokerCalls . get ( brokerId )
286+ if ( ! pending ) return
287+ clearTimeout ( pending . timeout )
288+ pendingBrokerCalls . delete ( brokerId )
289+ pending . resolve ( JSON . stringify ( { error : `Broker IPC send failed: ${ err . message } ` } ) )
290+ } )
264291 } )
265292 } )
266293 await jail . set ( '__brokerRef' , brokerCallback )
@@ -732,13 +759,19 @@ async function executeTask(request, executionId) {
732759 }
733760 } , BROKER_TIMEOUT_MS )
734761 pendingBrokerCalls . set ( brokerId , { resolve, timeout, executionId } )
735- if ( process . send && process . connected ) {
736- process . send ( { type : 'broker' , brokerId, executionId, brokerName, argsJson } )
737- } else {
762+ if ( ! process . send || ! process . connected ) {
738763 clearTimeout ( timeout )
739764 pendingBrokerCalls . delete ( brokerId )
740765 resolve ( JSON . stringify ( { error : 'Parent process disconnected' } ) )
766+ return
741767 }
768+ sendIpcRequest ( { type : 'broker' , brokerId, executionId, brokerName, argsJson } , ( err ) => {
769+ const pending = pendingBrokerCalls . get ( brokerId )
770+ if ( ! pending ) return
771+ clearTimeout ( pending . timeout )
772+ pendingBrokerCalls . delete ( brokerId )
773+ pending . resolve ( JSON . stringify ( { error : `Broker IPC send failed: ${ err . message } ` } ) )
774+ } )
742775 } )
743776 } )
744777 releaseables . push ( brokerRef )
0 commit comments