Codebase list golang-github-vbauerster-mpb / c6e22ac
recover with stack trace Vladimir Bauer 6 years ago
2 changed file(s) with 36 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
55 "fmt"
66 "io"
77 "log"
8 "runtime/debug"
89 "strings"
910 "time"
1011
297298 }
298299
299300 func (b *Bar) render(tw int) {
300 if b.recoveredPanic != nil {
301 b.toShutdown = false
302 b.frameCh <- b.panicToFrame(tw)
303 return
304 }
305 select {
306 case b.operateState <- func(s *bState) {
301 select {
302 case b.operateState <- func(s *bState) {
303 stat := newStatistics(tw, s)
307304 defer func() {
308305 // recovering if user defined decorator panics for example
309306 if p := recover(); p != nil {
307 var sb strings.Builder
308 fmt.Fprintf(&sb, "%#v\n", stat)
309 sb.Write(debug.Stack())
310 stack := sb.String()
311 nlc := strings.Count(stack, "\n")
312 s.extender = func(r io.Reader, _ int, _ decor.Statistics) (io.Reader, int) {
313 return io.MultiReader(r, strings.NewReader(stack)), nlc
314 }
315 b.recoveredPanic = p
316 b.extendedLines = nlc
317 b.toShutdown = true
318 b.frameCh <- io.MultiReader(b.panicToFrame(tw), strings.NewReader(stack))
310319 b.dlogger.Println(p)
311 b.recoveredPanic = p
312 b.toShutdown = !s.completeFlushed
313 b.frameCh <- b.panicToFrame(tw)
314320 }
315321 }()
316322
317 st := newStatistics(tw, s)
318 frame, lines := s.extender(s.draw(st), s.reqWidth, st)
323 frame, lines := s.extender(s.draw(stat), s.reqWidth, stat)
319324 b.extendedLines = lines
320325
321326 b.toShutdown = s.toComplete && !s.completeFlushed
324329 }:
325330 case <-b.done:
326331 s := b.cacheState
327 st := newStatistics(tw, s)
328 frame, lines := s.extender(s.draw(st), s.reqWidth, st)
332 stat := newStatistics(tw, s)
333 var r io.Reader
334 if b.recoveredPanic != nil {
335 r = b.panicToFrame(tw)
336 } else {
337 r = s.draw(stat)
338 }
339 frame, lines := s.extender(r, s.reqWidth, stat)
329340 b.extendedLines = lines
330341 b.frameCh <- frame
331342 }
332343 }
333344
334 func (b *Bar) panicToFrame(termWidth int) io.Reader {
335 return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%dv\n", termWidth), b.recoveredPanic))
345 func (b *Bar) panicToFrame(tw int) io.Reader {
346 return strings.NewReader(runewidth.Truncate(fmt.Sprint(b.recoveredPanic), tw, "…") + "\n")
336347 }
337348
338349 func (b *Bar) subscribeDecorators() {
246246 b := heap.Pop(&s.bHeap).(*Bar)
247247 cw.ReadFrom(<-b.frameCh)
248248 if b.toShutdown {
249 // shutdown at next flush
250 // this ensures no bar ends up with less than 100% rendered
251 defer func() {
249 if b.recoveredPanic != nil {
252250 s.barShutdownQueue = append(s.barShutdownQueue, b)
253 }()
251 b.toShutdown = false
252 } else {
253 // shutdown at next flush
254 // this ensures no bar ends up with less than 100% rendered
255 defer func() {
256 s.barShutdownQueue = append(s.barShutdownQueue, b)
257 }()
258 }
254259 }
255260 lineCount += b.extendedLines + 1
256261 bm[b] = struct{}{}