Skip to content

fix: proxy ESM loading, progress bar suppression, and temp directory handling#375

Merged
MarshallOfSound merged 9 commits intomainfrom
claude/identify-bugs-failing-tests-ymmHx
Mar 25, 2026
Merged

fix: proxy ESM loading, progress bar suppression, and temp directory handling#375
MarshallOfSound merged 9 commits intomainfrom
claude/identify-bugs-failing-tests-ymmHx

Conversation

@MarshallOfSound
Copy link
Copy Markdown
Member

Fixes five bugs uncovered during a code audit, plus one deprecation cleanup. Each fix is a separate commit.

Bugs fixed

initializeProxy() silently broken in ESM

src/proxy.ts called bare require('global-agent'), but the package is published as "type": "module" where require is undefined. The try/catch swallowed the ReferenceError, so proxy support never worked and users got no indication why. Fixed by defining require via createRequire(import.meta.url).

Progress bar suppression condition inverted

src/GotDownloader.ts:52 used !quiet || !process.env.ELECTRON_GET_NO_PROGRESS, which requires both flags to suppress the bar. Changed to && so either flag works as documented.

Progress timer leaks on download failure

When pipeline() threw, clearTimeout was never called, leaving a 30-second timer armed that would render a progress bar for an already-failed download. Moved cleanup into a finally block.

SHASUMS256.txt download ignores custom tempDirectory

The nested downloadArtifact call for checksum validation forwarded most options but omitted tempDirectory, so checksums were always written under os.tmpdir() regardless of caller configuration.

validateArtifact leaks empty temp directories

When cacheMode was ReadOnly or Bypass and checksums were not provided, the validation temp folder was created with ORPHAN mode but never cleaned up (the inner finally deleted the wrong directory). The validation folder never needs to outlive the function, so it now always uses CLEAN mode.

Refactor

Replace deprecated url.parse() with WHATWG URL

Cache.getCacheDirectory() used the legacy url.parse/url.format API. Switched to new URL(). Verified identical cache-directory hashes for all real-world Electron download URLs (github.com releases, nightlies, ports, userinfo); only the synthetic dummy:// test fixture hash changed.

Tests

New regression tests live in:

  • test/GotDownloader.spec.ts — progress bar suppression + timer cleanup (non-network)
  • test/proxy.spec.tscreateRequire guard
  • test/index.spec.tstempDirectory propagation + leak check (added to existing downloadArtifact suite)

73 tests passing, lint clean, build clean.

claude added 8 commits March 24, 2026 08:18
Adds test/bugs.spec.ts with 6 failing tests that demonstrate 5 bugs:

1. GotDownloader progress bar suppression uses || instead of &&,
   so neither quiet:true nor ELECTRON_GET_NO_PROGRESS alone
   suppresses the progress bar (src/GotDownloader.ts:52).

2. GotDownloader leaks its 30s progress timer when a download
   fails because clearTimeout is not in a finally block
   (src/GotDownloader.ts:79-91).

3. initializeProxy() calls require() which is undefined in ESM,
   silently breaking proxy support (src/proxy.ts:36).

4. validateArtifact() does not forward tempDirectory to the
   nested SHASUMS256.txt download, so checksums are written to
   os.tmpdir() regardless of user config (src/index.ts:77-88).

5. validateArtifact() leaks an empty temp directory when
   cacheMode is ReadOnly/Bypass and checksums are not provided,
   because the cleanup finally deletes the wrong directory
   (src/index.ts:111-120).
The package is published as ESM ("type": "module"), so bare
require() is undefined at runtime. The try/catch swallowed the
ReferenceError, causing proxy support to silently never work.

Define require via createRequire(import.meta.url) so the optional
dependency can be loaded synchronously as before.
The condition used || instead of &&, so neither `quiet: true`
alone nor ELECTRON_GET_NO_PROGRESS alone suppressed the progress
bar. Both had to be set simultaneously, contradicting the
documented behavior.
If pipeline() threw, the 30-second progress-bar timer was never
cleared and would fire after the download had already failed,
rendering a progress bar for a dead download. Move the cleanup
into a finally block.
The nested downloadArtifact call for checksum validation forwarded
most options but omitted tempDirectory, so SHASUMS256.txt was
always written under os.tmpdir() regardless of the caller's
configuration. This breaks setups where os.tmpdir() is read-only
or on a different filesystem.
validateArtifact created its temp directory with ORPHAN mode when
the caller owned the output (ReadOnly/Bypass cache modes), but the
validation tempFolder never needs to outlive the function. When
checksums were not provided, the inner finally block deleted the
SHASUMS256 download directory instead, leaving an empty
electron-download-* directory behind on every ReadOnly/Bypass
download. Always use CLEAN mode for the validation tempFolder.
url.parse() and url.format() (legacy) are deprecated since
Node.js 11. Switch to the WHATWG URL API.

The new implementation produces identical cache-directory hashes
for all real-world Electron download URLs (verified against
github.com, nightlies, ports, and userinfo). Only the synthetic
test fixture URL with no path component hashes differently, so
the hardcoded expected hash in Cache.spec.ts is updated.
Split the tests from bugs.spec.ts into:
- test/GotDownloader.spec.ts (progress bar and timer cleanup)
- test/proxy.spec.ts (createRequire guard)
- test/index.spec.ts (tempDirectory handling, added to existing
  downloadArtifact describe block)
@MarshallOfSound MarshallOfSound requested a review from a team as a code owner March 24, 2026 08:34
Lock in the cache-directory hash for a real Electron release URL
so any future URL-parsing change that would invalidate on-disk
caches fails this test instead of silently shipping.
@MarshallOfSound MarshallOfSound merged commit 5abedec into main Mar 25, 2026
6 checks passed
@MarshallOfSound MarshallOfSound deleted the claude/identify-bugs-failing-tests-ymmHx branch March 25, 2026 23:28
@electron-npm-package-publisher
Copy link
Copy Markdown

🎉 This PR is included in version 4.0.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants