Preserve joined rendering error evidence
This commit is contained in:
36
reporter.go
36
reporter.go
@@ -3,6 +3,7 @@ package commandkit
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -475,13 +476,46 @@ func finishRenderLocked(state *reportingState, destination reportingDestination,
|
||||
}
|
||||
|
||||
func recordRendererErrorLocked(state *reportingState, destination reportingDestination, renderErr, writeErr error) error {
|
||||
if renderErr == nil || (writeErr != nil && errors.Is(renderErr, writeErr)) {
|
||||
if renderErr == nil || (writeErr != nil && propagatesOnlyWriteError(renderErr, writeErr)) {
|
||||
return nil
|
||||
}
|
||||
state.recordRenderErrorLocked(destination, renderErr)
|
||||
return renderErr
|
||||
}
|
||||
|
||||
// A joined callback error may contain both a writer failure and independent
|
||||
// rendering evidence. Walk each branch once rather than discarding the entire
|
||||
// error merely because errors.Is finds the writer failure somewhere in it.
|
||||
func propagatesOnlyWriteError(err, writeErr error) bool {
|
||||
for err != nil {
|
||||
if reflect.TypeOf(err).Comparable() && err == writeErr {
|
||||
return true
|
||||
}
|
||||
switch wrapped := err.(type) {
|
||||
case interface{ Unwrap() []error }:
|
||||
found := false
|
||||
for _, child := range wrapped.Unwrap() {
|
||||
if child != nil {
|
||||
found = true
|
||||
if !propagatesOnlyWriteError(child, writeErr) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if found {
|
||||
return true
|
||||
}
|
||||
case interface{ Unwrap() error }:
|
||||
if child := wrapped.Unwrap(); child != nil {
|
||||
err = child
|
||||
continue
|
||||
}
|
||||
}
|
||||
return errors.Is(err, writeErr)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func combineOperationErrors(renderErr, writeErr error) error {
|
||||
switch {
|
||||
case renderErr == nil:
|
||||
|
||||
Reference in New Issue
Block a user