github.com/haraldrudell/parl@v0.4.176/internal/cyclebreaker/err-ch-wait.go (about)

     1  /*
     2  © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package cyclebreaker
     7  
     8  import "github.com/haraldrudell/parl/perrors"
     9  
    10  // ErrChWait is a deferrable function receiving an error value on a channel
    11  //   - used to wait for a goroutine
    12  //
    13  // Usage:
    14  //
    15  //	var err error
    16  //	defer errorHandler(&err)
    17  //
    18  //	var errCh = make(chan error, 1)
    19  //	go someFunc(errCh)
    20  //	defer parl.ErrChWait(errCh, &err)
    21  //
    22  //	func someFunc(errCh chan<- error) {
    23  //	  var err error
    24  //	  defer parl.SendErr(errCh, &err)
    25  //	  defer parl.PanicToErr(errp)
    26  func ErrChWait(errCh <-chan error, errp *error) {
    27  	if errp == nil {
    28  		panic(perrors.NewPF("errp cannot be nil"))
    29  	} else if errCh == nil {
    30  		panic(perrors.NewPF("errCh cannot be nil"))
    31  	}
    32  	// blocks here
    33  	if err := <-errCh; err != nil {
    34  		*errp = perrors.AppendError(*errp, err)
    35  	}
    36  }
    37  
    38  // SendErr sends error as the final action of a goroutine
    39  //   - SendErr should only panic from structural coding problems
    40  func SendErr(errCh chan<- error, errp *error) {
    41  	if errp == nil {
    42  		panic(perrors.NewPF("errp cannot be nil"))
    43  	}
    44  	didSend, isNilChannel, isClosedChannel, err := ChannelSend(errCh, *errp, SendNonBlocking)
    45  	if didSend {
    46  		return // error value sent return
    47  	} else if isNilChannel {
    48  		err = perrors.ErrorfPF("fatal: error channel nil: %w", err)
    49  	} else if isClosedChannel {
    50  		err = perrors.ErrorfPF("fatal: error channel closed: %w", err)
    51  	} else if err != nil {
    52  		err = perrors.ErrorfPF("fatal: panic when sending on error channel: %w", err)
    53  	} else {
    54  		err = perrors.NewPF("fatal: error channel blocking on send")
    55  	}
    56  	panic(err)
    57  }