@@ -174,6 +174,37 @@ pub struct ErrorsDuringDrain {
174
174
pub count : usize ,
175
175
}
176
176
177
+ struct ErrorToHandle {
178
+ error : anyhow:: Error ,
179
+
180
+ /// This field is true for "interesting" errors and false for "mundane"
181
+ /// errors. If false, we print the above error only if it's the first one
182
+ /// encountered so far while draining the job queue.
183
+ ///
184
+ /// At most places that an error is propagated, we set this to false to
185
+ /// avoid scenarios where Cargo might end up spewing tons of redundant error
186
+ /// messages. For example if an i/o stream got closed somewhere, we don't
187
+ /// care about individually reporting every thread that it broke; just the
188
+ /// first is enough.
189
+ ///
190
+ /// The exception where print_always is true is that we do report every
191
+ /// instance of a rustc invocation that failed with diagnostics. This
192
+ /// corresponds to errors from Message::Finish.
193
+ print_always : bool ,
194
+ }
195
+
196
+ impl < E > From < E > for ErrorToHandle
197
+ where
198
+ anyhow:: Error : From < E > ,
199
+ {
200
+ fn from ( error : E ) -> Self {
201
+ ErrorToHandle {
202
+ error : anyhow:: Error :: from ( error) ,
203
+ print_always : false ,
204
+ }
205
+ }
206
+ }
207
+
177
208
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
178
209
pub struct JobId ( pub u32 ) ;
179
210
@@ -617,7 +648,7 @@ impl<'cfg> DrainState<'cfg> {
617
648
jobserver_helper : & HelperThread ,
618
649
plan : & mut BuildPlan ,
619
650
event : Message ,
620
- ) -> CargoResult < ( ) > {
651
+ ) -> Result < ( ) , ErrorToHandle > {
621
652
match event {
622
653
Message :: Run ( id, cmd) => {
623
654
cx. bcx
@@ -682,11 +713,14 @@ impl<'cfg> DrainState<'cfg> {
682
713
debug ! ( "end ({:?}): {:?}" , unit, result) ;
683
714
match result {
684
715
Ok ( ( ) ) => self . finish ( id, & unit, artifact, cx) ?,
685
- Err ( e ) => {
716
+ Err ( error ) => {
686
717
let msg = "The following warnings were emitted during compilation:" ;
687
718
self . emit_warnings ( Some ( msg) , & unit, cx) ?;
688
719
self . back_compat_notice ( cx, & unit) ?;
689
- return Err ( e) ;
720
+ return Err ( ErrorToHandle {
721
+ error,
722
+ print_always : true ,
723
+ } ) ;
690
724
}
691
725
}
692
726
}
@@ -854,7 +888,7 @@ impl<'cfg> DrainState<'cfg> {
854
888
}
855
889
. to_json_string ( ) ;
856
890
if let Err ( e) = writeln ! ( shell. out( ) , "{}" , msg) {
857
- self . handle_error ( & mut shell, & mut errors, e. into ( ) ) ;
891
+ self . handle_error ( & mut shell, & mut errors, e) ;
858
892
}
859
893
}
860
894
@@ -887,13 +921,18 @@ impl<'cfg> DrainState<'cfg> {
887
921
& self ,
888
922
shell : & mut Shell ,
889
923
err_state : & mut ErrorsDuringDrain ,
890
- new_err : anyhow :: Error ,
924
+ new_err : impl Into < ErrorToHandle > ,
891
925
) {
892
- crate :: display_error ( & new_err, shell) ;
893
- if !self . active . is_empty ( ) && err_state. count == 0 {
894
- drop ( shell. warn ( "build failed, waiting for other jobs to finish..." ) ) ;
926
+ let new_err = new_err. into ( ) ;
927
+ if new_err. print_always || err_state. count == 0 {
928
+ crate :: display_error ( & new_err. error , shell) ;
929
+ if err_state. count == 0 && !self . active . is_empty ( ) {
930
+ drop ( shell. warn ( "build failed, waiting for other jobs to finish..." ) ) ;
931
+ }
932
+ err_state. count += 1 ;
933
+ } else {
934
+ log:: warn!( "{:?}" , new_err. error) ;
895
935
}
896
- err_state. count += 1 ;
897
936
}
898
937
899
938
// This also records CPU usage and marks concurrency; we roughly want to do
0 commit comments