Server up
Request received
First request worked
AxiosError: read ECONNRESET
at AxiosError.from (/Users/nikwen/Projects/Web/electron-utility-process-bug/node_modules/axios/dist/node/axios.cjs:873:14)
at RedirectableRequest.handleRequestError (/Users/nikwen/Projects/Web/electron-utility-process-bug/node_modules/axios/dist/node/axios.cjs:3152:25)
at RedirectableRequest.emit (node:events:519:28)
at eventHandlers.<computed> (/Users/nikwen/Projects/Web/electron-utility-process-bug/node_modules/follow-redirects/index.js:38:24)
at ClientRequest.emit (node:events:519:28)
at Socket.socketErrorListener (node:_http_client:500:9)
at Socket.emit (node:events:519:28)
at emitErrorNT (node:internal/streams/destroy:169:8)
at emitErrorCloseNT (node:internal/streams/destroy:128:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
at Axios.request (/Users/nikwen/Projects/Web/electron-utility-process-bug/node_modules/axios/dist/node/axios.cjs:4262:41)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async makeRequest (/Users/nikwen/Projects/Web/electron-utility-process-bug/src/utility.js:38:5) {
syscall: 'read',
code: 'ECONNRESET',
errno: -54,
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [ 'xhr', 'http', 'fetch' ],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function], Blob: [class Blob] },
validateStatus: [Function: validateStatus],
headers: Object [AxiosHeaders] {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'axios/1.7.3',
'Accept-Encoding': 'gzip, compress, deflate, br'
},
method: 'post',
url: 'http://127.0.0.1:3000',
data: undefined
},
request: <ref *1> Writable {
_events: {
close: undefined,
error: [Function: handleRequestError],
prefinish: undefined,
finish: undefined,
drain: undefined,
response: [Function: handleResponse],
socket: [Function: handleRequestSocket]
},
_writableState: WritableState {
highWaterMark: 16384,
length: 0,
corked: 0,
onwrite: [Function: bound onwrite],
writelen: 0,
bufferedIndex: 0,
pendingcb: 0,
[Symbol(kState)]: 17580812,
[Symbol(kBufferedValue)]: null
},
_maxListeners: undefined,
_options: {
maxRedirects: 21,
maxBodyLength: Infinity,
protocol: 'http:',
path: '/',
method: 'POST',
headers: [Object: null prototype],
agents: [Object],
auth: undefined,
family: undefined,
beforeRedirect: [Function: dispatchBeforeRedirect],
beforeRedirects: [Object],
hostname: '127.0.0.1',
port: '3000',
agent: undefined,
nativeProtocols: [Object],
pathname: '/'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_eventsCount: 3,
_onNativeResponse: [Function (anonymous)],
_currentRequest: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: [Socket],
_header: 'POST / HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/x-www-form-urlencoded\r\n' +
'User-Agent: axios/1.7.3\r\n' +
'Accept-Encoding: gzip, compress, deflate, br\r\n' +
'Host: 127.0.0.1:3000\r\n' +
'Connection: keep-alive\r\n' +
'Content-Length: 0\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/',
_ended: false,
res: null,
aborted: false,
timeoutCb: [Function: emitRequestTimeout],
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: true,
host: '127.0.0.1',
protocol: 'http:',
_redirectable: [Circular *1],
[Symbol(shapeMode)]: false,
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kHighWaterMark)]: 16384,
[Symbol(kRejectNonStandardBodyWrites)]: false,
[Symbol(kUniqueHeaders)]: null
},
_currentUrl: 'http://127.0.0.1:3000/',
[Symbol(shapeMode)]: true,
[Symbol(kCapture)]: false
},
cause: Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:218:20) {
errno: -54,
code: 'ECONNRESET',
syscall: 'read'
}
}
Preflight Checklist
Electron Version
31.3.1
What operating system(s) are you using?
macOS
Operating System Version
macOS Sonoma 14.6
What arch are you using?
arm64 (including Apple Silicon)
Last Known Working Electron version
28.3.3
Expected Behavior
Network requests work when performed after long-running tasks in a utility process.
Actual Behavior
If code in a utility process blocks the event loop for a few seconds and then performs a network request, that network request fails with
ECONNRESET. If we wait for 10ms before running the network request, it works.This is bad because utility processes are made for these long-running tasks that can block the event loop. We don't want that code in our main processes.
This is a regression in Electron v29 and above (via #40017?). The code runs fine on Electron v28.
Testcase Gist URL
https://gist.github.com/nikwen/6a66d9fa7a469a266490e88fa0c8222a
Additional Information
Full command line output & error message
From the previous reproduction code (because Fiddle cuts off the error message).
Show
Affected platforms