github.com/blend/go-sdk@v1.20220411.3/examples/db/prevent-deadlock/multi.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package main
     9  
    10  import (
    11  	"fmt"
    12  	"strings"
    13  )
    14  
    15  // NOTE: Ensure that
    16  //       * `multiError` satisfies `error`.
    17  var (
    18  	_ error = (*multiError)(nil)
    19  )
    20  
    21  type multiError struct {
    22  	Errors []error
    23  }
    24  
    25  func (me *multiError) Error() string {
    26  	if me == nil || len(me.Errors) == 0 {
    27  		return "<nil>"
    28  	}
    29  	parts := []string{}
    30  	for _, err := range me.Errors {
    31  		parts = append(parts, fmt.Sprintf("- %#v", err))
    32  	}
    33  	return strings.Join(parts, "\n")
    34  }
    35  
    36  func nest(err1, err2 error) error {
    37  	asMulti1, ok1 := err1.(*multiError)
    38  	asMulti2, ok2 := err2.(*multiError)
    39  
    40  	if err1 == nil {
    41  		if err2 == nil {
    42  			return nil
    43  		}
    44  		if ok2 {
    45  			return err2
    46  		}
    47  		return &multiError{Errors: []error{err2}}
    48  	}
    49  
    50  	if err2 == nil {
    51  		if ok1 {
    52  			return err1
    53  		}
    54  		return &multiError{Errors: []error{err1}}
    55  	}
    56  
    57  	// We know below here that both errors are non-nil.
    58  	if ok1 {
    59  		if ok2 {
    60  			return &multiError{Errors: append(asMulti1.Errors, asMulti2.Errors...)}
    61  		}
    62  
    63  		return &multiError{Errors: append(asMulti1.Errors, err2)}
    64  	}
    65  
    66  	if ok2 {
    67  		return &multiError{Errors: append(asMulti2.Errors, err1)}
    68  	}
    69  
    70  	return &multiError{Errors: []error{err1, err2}}
    71  }