| 513 | } |
| 514 | |
| 515 | func (s *state) collectEntry(err error, bufIsRedactable bool, withDepth bool, depth int) formatEntry { |
| 516 | entry := formatEntry{err: err} |
| 517 | if s.wantDetail { |
| 518 | // The buffer has been populated as a result of formatting with |
| 519 | // %+v. In that case, if the printer has separated detail |
| 520 | // from non-detail, we can use the split. |
| 521 | if s.hasDetail { |
| 522 | entry.head = s.headBuf |
| 523 | entry.details = s.buf.Bytes() |
| 524 | } else { |
| 525 | entry.head = s.buf.Bytes() |
| 526 | } |
| 527 | } else { |
| 528 | entry.head = s.headBuf |
| 529 | if len(entry.head) > 0 && entry.head[len(entry.head)-1] != '\n' && |
| 530 | s.buf.Len() > 0 && s.buf.Bytes()[0] != '\n' { |
| 531 | entry.head = append(entry.head, '\n') |
| 532 | } |
| 533 | entry.head = append(entry.head, s.buf.Bytes()...) |
| 534 | } |
| 535 | |
| 536 | if bufIsRedactable { |
| 537 | // In this case, we've produced entry.head/entry.details using a |
| 538 | // SafeFormatError() invocation. The strings in |
| 539 | // entry.head/entry.detail contain redaction markers at this |
| 540 | // point. |
| 541 | if s.redactableOutput { |
| 542 | // Redaction markers desired in the final output. Keep the |
| 543 | // redaction markers. |
| 544 | entry.redactable = true |
| 545 | } else { |
| 546 | // Markers not desired in the final output: strip the markers. |
| 547 | entry.head = redact.RedactableBytes(entry.head).StripMarkers() |
| 548 | entry.details = redact.RedactableBytes(entry.details).StripMarkers() |
| 549 | } |
| 550 | } |
| 551 | |
| 552 | if withDepth { |
| 553 | entry.depth = depth |
| 554 | } |
| 555 | |
| 556 | return entry |
| 557 | } |
| 558 | |
| 559 | // safeErrorPrinterFn is the type of a function that can take |
| 560 | // over the safe printing of an error. This is used to inject special |