Skip to content
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

fix: avoid grouping logs from tasks which ended in error #7335

Merged
merged 6 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion crates/turborepo-lib/src/task_graph/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,10 @@ impl ExecContext {
.instrument(span)
.await;

let logs = match output_client.finish() {
// If the task resulted in an error, do not group in order to better highlight
// the error.
let keep_group = matches!(result, ExecOutcome::Success(_));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woah, TIL about matches!. Love that.

let logs = match output_client.finish(keep_group) {
Ok(logs) => logs,
Err(e) => {
telemetry.track_error(TrackedErrors::DaemonFailedToMarkOutputsAsCached);
Expand Down
22 changes: 11 additions & 11 deletions crates/turborepo-ui/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl<W: Write> OutputClient<W> {

/// Consume the client and flush any bytes to the underlying sink if
/// necessary
pub fn finish(self) -> io::Result<Option<Vec<u8>>> {
pub fn finish(self, keep_group: bool) -> io::Result<Option<Vec<u8>>> {
let Self {
behavior,
buffer,
Expand All @@ -133,7 +133,7 @@ impl<W: Write> OutputClient<W> {
// We hold the mutex until we write all of the bytes associated for the client
// to ensure that the bytes aren't interspersed.
let mut writers = writers.lock().expect("lock poisoned");
if let Some(prefix) = header {
if let Some(prefix) = keep_group.then_some(header).flatten() {
writers.out.write_all(prefix.as_bytes())?;
}
for SinkBytes {
Expand All @@ -147,7 +147,7 @@ impl<W: Write> OutputClient<W> {
};
writer.write_all(buffer)?;
}
if let Some(suffix) = footer {
if let Some(suffix) = keep_group.then_some(footer).flatten() {
writers.out.write_all(suffix.as_bytes())?;
}
}
Expand Down Expand Up @@ -253,15 +253,15 @@ mod test {
let mut err = pass_thru_logger.stderr();
writeln!(&mut out, "task 1: out").unwrap();
writeln!(&mut err, "task 1: err").unwrap();
assert!(pass_thru_logger.finish().unwrap().is_none());
assert!(pass_thru_logger.finish(true).unwrap().is_none());
});
s.spawn(move || {
let mut out = buffer_logger.stdout();
let mut err = buffer_logger.stderr();
writeln!(&mut out, "task 2: out").unwrap();
writeln!(&mut err, "task 2: err").unwrap();
assert_eq!(
buffer_logger.finish().unwrap().unwrap(),
buffer_logger.finish(true).unwrap().unwrap(),
b"task 2: out\ntask 2: err\n"
);
});
Expand Down Expand Up @@ -291,7 +291,7 @@ mod test {
"pass thru should end up in sink immediately"
);
assert!(
logger.finish()?.is_none(),
logger.finish(true)?.is_none(),
"pass through logs shouldn't keep a buffer"
);
assert_eq!(
Expand All @@ -317,7 +317,7 @@ mod test {
"buffer should end up in sink immediately"
);
assert_eq!(
logger.finish()?.unwrap(),
logger.finish(true)?.unwrap(),
b"output for 1\n",
"buffer should return buffer"
);
Expand All @@ -343,11 +343,11 @@ mod test {
writeln!(&mut group2_out, "output for 2")?;
writeln!(&mut group1_out, "output for 1")?;
let group1_logs = group1_logger
.finish()?
.finish(true)?
.expect("grouped logs should have buffer");
writeln!(&mut group2_err, "warning for 2")?;
let group2_logs = group2_logger
.finish()?
.finish(true)?
.expect("grouped logs should have buffer");

assert_eq!(group1_logs, b"output for 1\n");
Expand All @@ -374,14 +374,14 @@ mod test {
write!(&mut out, "task 1:").unwrap();
b1.wait();
writeln!(&mut out, " echo building").unwrap();
assert!(logger1.finish().unwrap().is_none());
assert!(logger1.finish(true).unwrap().is_none());
});
s.spawn(move || {
let mut out = logger2.stdout();
write!(&mut out, "task 2:").unwrap();
b2.wait();
writeln!(&mut out, " echo failing").unwrap();
assert!(logger2.finish().unwrap().is_none(),);
assert!(logger2.finish(true).unwrap().is_none(),);
});
});
let SinkWriters { out, .. } = Arc::into_inner(sink.writers).unwrap().into_inner().unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ Verify that errors are grouped properly
\xe2\x80\xa2 Packages in scope: my-app, util (esc)
\xe2\x80\xa2 Running fail in 2 packages (esc)
\xe2\x80\xa2 Remote caching disabled (esc)
::group::util:fail
cache miss, executing 122cca10fdcda4f0

\> fail (re)
Expand All @@ -68,7 +67,6 @@ Verify that errors are grouped properly
npm ERR! in workspace: util
npm ERR\! at location: (.*)(\/|\\)packages(\/|\\)util (re)
\[ERROR\] command finished with error: command \((.*)(\/|\\)packages(\/|\\)util\) (.*)npm(?:\.cmd)? run fail exited \(1\) (re)
::endgroup::
::error::util#fail: command \(.*(\/|\\)packages(\/|\\)util\) (.*)npm(?:\.cmd)? run fail exited \(1\) (re)

Tasks: 0 successful, 1 total
Expand Down
Loading