-
Notifications
You must be signed in to change notification settings - Fork 3.3k
fix: Redirect spammy electron stderr to a debug sink #32188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 57 commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
3e772ee
wip: system test to reproduce
cacieprins d830ed8
system test for alsa stderr
cacieprins 5f8528a
split cypress from 3rd party stderr at parent process to electron child
cacieprins f618cd6
rm garbage warning regexes
cacieprins de717a7
fix newline behavior when parsing internal stderr
cacieprins 5fa8203
migrate left over console errors
cacieprins 734e611
clean up system test name
cacieprins 866415f
fix typed import
cacieprins 87d5fa9
extract stderr splitting to separate pkg so runner can use @packages/…
cacieprins 7d9898e
rm new err log from packherd-quire
cacieprins dd646b3
handle backpressure
cacieprins a3f935e
docs
cacieprins a893e29
some unit tests & coverage for stderr-filtering
cacieprins 69487a0
unit tests
cacieprins b2ab667
no longer test regexp specific output in spawn unit tests
cacieprins a60d4f8
filter enabled debug namespaces rather than just cypress namespacesc
cacieprins c5eae1c
revise stream splitting et al
cacieprins 2bbf290
try to fix v8 snapshot build??
cacieprins 53764e9
Merge branch 'develop' into fix/audio-error-stdout
cacieprins bb32eb6
fix console.log assertion
cacieprins 3bf6824
add missing eslint config
cacieprins 256ee49
rm unused spies
cacieprins bc87235
fix regexp for optional leading wsp and ansi on debug entries
cacieprins 4760d92
update unit tests because sinon
cacieprins 7139dfc
lint
cacieprins ecd3ebd
colon..
cacieprins 3f205cc
build stderr-filtering before checking if binary exists
cacieprins b5a2877
adds TagStream transform stream, fixes stderr from child proc config
cacieprins 0415b4e
add build-prod script for stderr-filtering
cacieprins 443f669
changelog
cacieprins b5035ac
Merge branch 'develop' into fix/audio-error-stdout
cacieprins 2cc0265
properly handle backpressure in prefixed content transform stream
cacieprins a49a6ea
use standard tsconfig?
cacieprins 62589f9
better tsconfig
cacieprins 09d5937
Add pkgStderrFiltering to monorepoPaths
jennifer-shehane 3953456
add \"files\" manifest
cacieprins b24aa0b
pipe all stderr to stderr when CYPRESS_INTERNAL_DEBUG_ELECTRON is ena…
cacieprins 33e6b54
Merge branch 'develop' into fix/audio-error-stdout
jennifer-shehane b1f1b69
rm explicit build of stderr-filtering in check-if-binary-exists step
cacieprins 7ae230e
ensure all dependencies of scripts/ are built before scripts are exec…
cacieprins 0ddf849
fix dev version ref
cacieprins 72a6a34
swap logic
cacieprins b241c67
add stdin piping
cacieprins 8a4f1ea
fix exec name on the run-on-dependencies command to be more useful
cacieprins 6e35818
use correct env
cacieprins 8d82ccb
Merge branch 'develop' into fix/audio-error-stdout
cacieprins c9aa13e
rm obsolete type refs
cacieprins 96f9b9e
Merge branch 'develop' into fix/audio-error-stdout
cacieprins b93c9fe
simplify stderr-filtering public iface, pipe cy-in-cy stderr through …
cacieprins e4f02d2
bust cache
cacieprins 0c2b8b3
fix mocks
cacieprins ae43933
Merge branch 'develop' into fix/audio-error-stdout
cacieprins 5e653d6
fix v8-snapshot
AtofStryker eba73d0
move stderrfiltering to dev pkg in cli
cacieprins 8ebc620
skip integrity check in ci, if they are out of date things should fai…
cacieprins 52e67f2
copypasta over a portion of stderr-filtering to cli, since cli cannot…
cacieprins 996429f
Delete issues.md
cacieprins 9bd788b
rm special filtering for cy in cy
cacieprins fea55c1
rm too narrow rules file
cacieprins File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
# Bump this version to force CI to re-create the cache from scratch. | ||
8-13-2025 | ||
8-19-2025 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
'use strict' | ||
let __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { 'default': mod } | ||
} | ||
|
||
Object.defineProperty(exports, '__esModule', { value: true }) | ||
exports.FilterTaggedContent = void 0 | ||
|
||
const stream_1 = require('stream') | ||
const string_decoder_1 = require('string_decoder') | ||
const LineDecoder_1 = require('./LineDecoder') | ||
const debug_1 = __importDefault(require('debug')) | ||
const writeWithBackpressure_1 = require('./writeWithBackpressure') | ||
const debug = (0, debug_1.default)('cypress:stderr-filtering:FilterTaggedContent') | ||
|
||
/** | ||
* Filters content based on start and end tags, supporting multi-line tagged content. | ||
* | ||
* This transform stream processes incoming data and routes content between two output streams | ||
* based on tag detection. Content between start and end tags is sent to the filtered stream, | ||
* while content outside tags is sent to the main output stream. The class handles cases where | ||
* tags span multiple lines by maintaining state across line boundaries. | ||
* | ||
* Example usage: | ||
* ```typescript | ||
* const filter = new FilterTaggedContent('<secret>', '</secret>', filteredStream) | ||
* inputStream.pipe(filter).pipe(outputStream) | ||
* ``` | ||
*/ | ||
class FilterTaggedContent extends stream_1.Transform { | ||
/** | ||
* Creates a new FilterTaggedContent instance. | ||
* | ||
* @param startTag The string that marks the beginning of content to filter | ||
* @param endTag The string that marks the end of content to filter | ||
* @param filtered The writable stream for filtered content | ||
*/ | ||
constructor (startTag, endTag, wasteStream) { | ||
super({ | ||
transform: (chunk, encoding, next) => this.transform(chunk, encoding, next), | ||
flush: (callback) => this.flush(callback), | ||
}) | ||
|
||
this.startTag = startTag | ||
this.endTag = endTag | ||
this.wasteStream = wasteStream | ||
this.inTaggedContent = false | ||
/** | ||
* Processes incoming chunks and routes content based on tag detection. | ||
* | ||
* @param chunk The buffer chunk to process | ||
* @param encoding The encoding of the chunk | ||
* @param next Callback to call when processing is complete | ||
*/ | ||
this.transform = async (chunk, encoding, next) => { | ||
let _a; let _b; let _c | ||
|
||
try { | ||
this.ensureDecoders(encoding) | ||
const str = (_b = (_a = this.strDecoder) === null || _a === void 0 ? void 0 : _a.write(chunk)) !== null && _b !== void 0 ? _b : ''; | ||
|
||
(_c = this.lineDecoder) === null || _c === void 0 ? void 0 : _c.write(str) | ||
debug('processing str for tags: "%s"', str) | ||
for (const line of Array.from(this.lineDecoder || [])) { | ||
await this.processLine(line) | ||
} | ||
next() | ||
} catch (err) { | ||
next(err) | ||
} | ||
} | ||
|
||
/** | ||
* Flushes any remaining buffered content when the stream ends. | ||
* | ||
* @param callback Callback to call when flushing is complete | ||
*/ | ||
this.flush = async (callback) => { | ||
let _a | ||
|
||
debug('flushing') | ||
this.ensureDecoders() | ||
try { | ||
for (const line of Array.from(((_a = this.lineDecoder) === null || _a === void 0 ? void 0 : _a.end()) || [])) { | ||
await this.processLine(line) | ||
} | ||
callback() | ||
} catch (err) { | ||
callback(err) | ||
} | ||
} | ||
} | ||
ensureDecoders (encoding) { | ||
let _a | ||
const enc = (_a = (encoding === 'buffer' ? 'utf8' : encoding)) !== null && _a !== void 0 ? _a : 'utf8' | ||
|
||
if (!this.lineDecoder) { | ||
this.lineDecoder = new LineDecoder_1.LineDecoder() | ||
} | ||
|
||
if (!this.strDecoder) { | ||
this.strDecoder = new string_decoder_1.StringDecoder(enc) | ||
} | ||
} | ||
/** | ||
* Processes a single line and routes content based on tag positions. | ||
* | ||
* This method handles the complex logic of detecting start and end tags within a line, | ||
* maintaining state across lines, and routing content to the appropriate streams. | ||
* It supports cases where both tags appear on the same line, only one tag appears, | ||
* or no tags appear but the line is part of ongoing tagged content. | ||
* | ||
* @param line The line to process | ||
*/ | ||
async processLine (line) { | ||
const startPos = line.indexOf(this.startTag) | ||
const endPos = line.lastIndexOf(this.endTag) | ||
|
||
if (startPos >= 0 && endPos >= 0) { | ||
// Both tags on same line | ||
if (startPos > 0) { | ||
await this.pass(line.slice(0, startPos)) | ||
} | ||
|
||
await this.writeToWasteStream(line.slice(startPos + this.startTag.length, endPos)) | ||
if (endPos + this.endTag.length < line.length) { | ||
await this.pass(line.slice(endPos + this.endTag.length)) | ||
} | ||
} else if (startPos >= 0) { | ||
// Start tag found | ||
if (startPos > 0) { | ||
await this.pass(line.slice(0, startPos)) | ||
} | ||
|
||
await this.writeToWasteStream(line.slice(startPos + this.startTag.length)) | ||
this.inTaggedContent = true | ||
} else if (endPos >= 0) { | ||
// End tag found | ||
await this.writeToWasteStream(line.slice(0, endPos)) | ||
if (endPos + this.endTag.length < line.length) { | ||
await this.pass(line.slice(endPos + this.endTag.length)) | ||
} | ||
|
||
this.inTaggedContent = false | ||
} else if (this.inTaggedContent) { | ||
// Currently in tagged content | ||
await this.writeToWasteStream(line) | ||
} else { | ||
// Not in tagged content | ||
await this.pass(line) | ||
} | ||
} | ||
async writeToWasteStream (line, encoding) { | ||
let _a | ||
|
||
debug('writing to waste stream: "%s"', line) | ||
await (0, writeWithBackpressure_1.writeWithBackpressure)(this.wasteStream, Buffer.from(line, (_a = (encoding === 'buffer' ? 'utf8' : encoding)) !== null && _a !== void 0 ? _a : 'utf8')) | ||
} | ||
async pass (line, encoding) { | ||
let _a | ||
|
||
debug('passing: "%s"', line) | ||
this.push(Buffer.from(line, (_a = (encoding === 'buffer' ? 'utf8' : encoding)) !== null && _a !== void 0 ? _a : 'utf8')) | ||
} | ||
} | ||
exports.FilterTaggedContent = FilterTaggedContent |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.