makePanicExtender
Vladimir Bauer
6 years ago
| 304 | 304 | defer func() { |
| 305 | 305 | // recovering if user defined decorator panics for example |
| 306 | 306 | 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 | } | |
| 307 | go b.dlogger.Println(p) | |
| 308 | s.extender = makePanicExtender(p) | |
| 309 | frame, lines := s.extender(nil, s.reqWidth, stat) | |
| 310 | b.extendedLines = lines | |
| 311 | b.toShutdown = true | |
| 315 | 312 | b.recoveredPanic = p |
| 316 | b.extendedLines = nlc | |
| 317 | b.toShutdown = true | |
| 318 | b.frameCh <- io.MultiReader(b.panicToFrame(tw), strings.NewReader(stack)) | |
| 319 | b.dlogger.Println(p) | |
| 313 | b.frameCh <- frame | |
| 320 | 314 | } |
| 321 | 315 | }() |
| 322 | ||
| 323 | 316 | frame, lines := s.extender(s.draw(stat), s.reqWidth, stat) |
| 324 | 317 | b.extendedLines = lines |
| 325 | ||
| 326 | 318 | b.toShutdown = s.toComplete && !s.completeFlushed |
| 327 | 319 | s.completeFlushed = s.toComplete |
| 328 | 320 | b.frameCh <- frame |
| 331 | 323 | s := b.cacheState |
| 332 | 324 | stat := newStatistics(tw, s) |
| 333 | 325 | var r io.Reader |
| 334 | if b.recoveredPanic != nil { | |
| 335 | r = b.panicToFrame(tw) | |
| 336 | } else { | |
| 326 | if b.recoveredPanic == nil { | |
| 337 | 327 | r = s.draw(stat) |
| 338 | 328 | } |
| 339 | 329 | frame, lines := s.extender(r, s.reqWidth, stat) |
| 340 | 330 | b.extendedLines = lines |
| 341 | 331 | b.frameCh <- frame |
| 342 | 332 | } |
| 343 | } | |
| 344 | ||
| 345 | func (b *Bar) panicToFrame(tw int) io.Reader { | |
| 346 | return strings.NewReader(runewidth.Truncate(fmt.Sprint(b.recoveredPanic), tw, "…") + "\n") | |
| 347 | 333 | } |
| 348 | 334 | |
| 349 | 335 | func (b *Bar) subscribeDecorators() { |
| 475 | 461 | d.EwmaUpdate(s.lastN, dur) |
| 476 | 462 | } |
| 477 | 463 | } |
| 464 | ||
| 465 | func makePanicExtender(p interface{}) extFunc { | |
| 466 | pstr := fmt.Sprint(p) | |
| 467 | stack := debug.Stack() | |
| 468 | stackLines := bytes.Count(stack, []byte("\n")) | |
| 469 | return func(_ io.Reader, _ int, st decor.Statistics) (io.Reader, int) { | |
| 470 | mr := io.MultiReader( | |
| 471 | strings.NewReader(runewidth.Truncate(pstr, st.AvailableWidth, "…")), | |
| 472 | strings.NewReader(fmt.Sprintf("\n%#v\n", st)), | |
| 473 | bytes.NewReader(stack), | |
| 474 | ) | |
| 475 | return mr, stackLines + 1 | |
| 476 | } | |
| 477 | } | |