@@ -62,7 +62,6 @@ use slog::{BorrowedKV, Level, Record, RecordStatic, SingleKV, KV};
6262use slog:: { Key , OwnedKVList , Serializer } ;
6363
6464use slog:: Drain ;
65- use std:: error:: Error ;
6665use std:: fmt;
6766use std:: sync;
6867use std:: { io, thread} ;
@@ -71,6 +70,8 @@ use std::sync::atomic::AtomicUsize;
7170use std:: sync:: atomic:: Ordering ;
7271use std:: sync:: Mutex ;
7372use take_mut:: take;
73+
74+ use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
7475// }}}
7576
7677// {{{ Serializer
@@ -222,7 +223,7 @@ impl<T> From<std::sync::PoisonError<T>> for AsyncError {
222223 fn from ( err : std:: sync:: PoisonError < T > ) -> AsyncError {
223224 AsyncError :: Fatal ( Box :: new ( io:: Error :: new (
224225 io:: ErrorKind :: BrokenPipe ,
225- err. description ( ) ,
226+ err. to_string ( ) ,
226227 ) ) )
227228 }
228229}
@@ -294,12 +295,25 @@ where
294295 }
295296 let drain = self . drain ;
296297 let join = builder
297- . spawn ( move || loop {
298- match rx. recv ( ) . unwrap ( ) {
299- AsyncMsg :: Record ( r) => {
300- r. log_to ( & drain) . unwrap ( ) ;
298+ . spawn ( move || {
299+ let drain = AssertUnwindSafe ( & drain) ;
300+ // catching possible unwinding panics which can occur in used inner Drain implementation
301+ if let Err ( panic_cause) = catch_unwind ( move || loop {
302+ match rx. recv ( ) {
303+ Ok ( AsyncMsg :: Record ( r) ) => {
304+ if r. log_to ( & * drain) . is_err ( ) {
305+ eprintln ! ( "slog-async failed while writing" ) ;
306+ return ;
307+ }
308+ }
309+ Ok ( AsyncMsg :: Finish ) => return ,
310+ Err ( recv_error) => {
311+ eprintln ! ( "slog-async failed while receiving: {recv_error}" ) ;
312+ return ;
313+ }
301314 }
302- AsyncMsg :: Finish => return ,
315+ } ) {
316+ eprintln ! ( "slog-async failed with panic: {panic_cause:?}" )
303317 }
304318 } )
305319 . unwrap ( ) ;
0 commit comments