refactoring: bar panic recover
Vladimir Bauer
7 years ago
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | dlogger *log.Logger |
| 59 | bpanic interface{} | |
| 59 | 60 | } |
| 60 | 61 | |
| 61 | 62 | type bState struct { |
| 75 | 76 | shutdownListeners []decor.ShutdownListener |
| 76 | 77 | bufP, bufB, bufA *bytes.Buffer |
| 77 | 78 | bufE *bytes.Buffer |
| 78 | panicMsg string | |
| 79 | 79 | |
| 80 | 80 | // priority overrides *Bar's priority, if set |
| 81 | 81 | priority int |
| 267 | 267 | } |
| 268 | 268 | |
| 269 | 269 | func (b *Bar) render(debugOut io.Writer, tw int) { |
| 270 | if b.bpanic != nil { | |
| 271 | b.toShutdown = false | |
| 272 | b.frameCh <- b.panicToFrame(tw) | |
| 273 | return | |
| 274 | } | |
| 270 | 275 | select { |
| 271 | 276 | case b.operateState <- func(s *bState) { |
| 272 | 277 | defer func() { |
| 273 | 278 | // recovering if user defined decorator panics for example |
| 274 | 279 | if p := recover(); p != nil { |
| 275 | 280 | b.dlogger.Println(p) |
| 276 | s.panicMsg = fmt.Sprintf("panic: %v", p) | |
| 277 | close(b.shutdown) | |
| 278 | b.frameCh <- s.drawPanic(tw) | |
| 281 | b.bpanic = p | |
| 282 | b.toShutdown = !s.completeFlushed | |
| 283 | b.frameCh <- b.panicToFrame(tw) | |
| 279 | 284 | } |
| 280 | 285 | }() |
| 281 | 286 | |
| 282 | 287 | frame := s.draw(tw) |
| 283 | b.toShutdown = s.toComplete && !s.completeFlushed | |
| 284 | s.completeFlushed = s.toComplete | |
| 285 | 288 | |
| 286 | 289 | if s.extender != nil { |
| 287 | 290 | s.extender.Fill(s.bufE, tw, newStatistics(s)) |
| 288 | 291 | b.extendedLines = countLines(s.bufE.Bytes()) |
| 289 | 292 | frame = io.MultiReader(frame, s.bufE) |
| 290 | 293 | } |
| 294 | ||
| 295 | b.toShutdown = s.toComplete && !s.completeFlushed | |
| 296 | s.completeFlushed = s.toComplete | |
| 297 | ||
| 291 | 298 | b.frameCh <- frame |
| 292 | 299 | }: |
| 293 | 300 | case <-b.done: |
| 294 | 301 | s := b.cacheState |
| 295 | if s.panicMsg != "" { | |
| 296 | b.frameCh <- s.drawPanic(tw) | |
| 297 | return | |
| 298 | } | |
| 299 | 302 | frame := s.draw(tw) |
| 300 | 303 | if s.extender != nil { |
| 301 | 304 | s.extender.Fill(s.bufE, tw, newStatistics(s)) |
| 306 | 309 | } |
| 307 | 310 | } |
| 308 | 311 | |
| 309 | func (s *bState) drawPanic(termWidth int) io.Reader { | |
| 310 | return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", termWidth), s.panicMsg)) | |
| 312 | func (b *Bar) panicToFrame(termWidth int) io.Reader { | |
| 313 | return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%dv\n", termWidth), b.bpanic)) | |
| 311 | 314 | } |
| 312 | 315 | |
| 313 | 316 | func (s *bState) draw(termWidth int) io.Reader { |