github.com/packtpublishing/learning-functional-programming-in-go@v0.0.0-20230130084745-8b849f6d58c4/Chapter06/04_onion/src/utils/utils.go (about)

     1  package utils
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"os"
     9  	"path"
    10  	"runtime"
    11  	"time"
    12  	"strings"
    13  )
    14  
    15  type APIError struct {
    16  	ErrorMessage string `json:"error_message"`
    17  	HTTPStatus   int    `json:"http_status"`
    18  }
    19  
    20  type HttpErrorHandler struct {
    21  	Caller   string
    22  	Response http.ResponseWriter
    23  	Request  *http.Request
    24  }
    25  
    26  const (
    27  	ErrorActionErr = iota
    28  	ErrorActionWarn
    29  	ErrorActionDebug
    30  	ErrorActionInfo
    31  )
    32  
    33  func NewHttpErrorHandle(caller string, response http.ResponseWriter, request *http.Request) *HttpErrorHandler {
    34  	return &HttpErrorHandler{caller, response, request}
    35  }
    36  
    37  // HandleError locally, according to the action passed to h.Handle, and then serialized
    38  // in json and sent to the remote address via http, then returns true.
    39  // Otherwise, if there is no error, h.Handle returns false
    40  func (h *HttpErrorHandler) Handle(err error, httpStatus int, action int) bool {
    41  	if err != nil {
    42  		_, filepath, line, _ := runtime.Caller(1)
    43  		_, file := path.Split(filepath)
    44  		Error.Printf("HttpErrorHandler()->[file:%s line:%d]: %s", file, line, err.Error())
    45  		apiErr := &APIError{
    46  			ErrorMessage: err.Error(),
    47  			HTTPStatus:   httpStatus,
    48  		}
    49  		serialErr, _ := json.Marshal(&apiErr)
    50  		h.Response.Header().Set("Content-Type", "application/json")
    51  		h.Response.WriteHeader(httpStatus)
    52  		io.WriteString(h.Response, string(serialErr))
    53  	}
    54  	return (err != nil)
    55  }
    56  
    57  // HandlePanic _Never_ returns on error, instead it panics
    58  func FromLineOfFile() string {
    59  		_, filepath, line, _ := runtime.Caller(1)
    60  		_, file := path.Split(filepath)
    61  		return fmt.Sprintf("[file:%s line:%d]", file, line)
    62  }
    63  
    64  // HandlePanic _Never_ returns an error, instead it panics
    65  func HandlePanic(err error) {
    66  	if err != nil {
    67  		_, filePath, lineNo, _ := runtime.Caller(1)
    68  		_, fileName := path.Split(filePath)
    69  		msg := fmt.Sprintf("[file:%s line:%d]: %s", fileName, lineNo, err.Error())
    70  		panic(msg)
    71  	}
    72  }
    73  
    74  func HandleError(err error, action int) bool {
    75  	if err != nil {
    76  		_, filepath, line, _ := runtime.Caller(1)
    77  		_, file := path.Split(filepath)
    78  		switch action {
    79  		case ErrorActionErr:
    80  			Error.Printf("[file:%s line:%d]: %s", file, line, err.Error())
    81  			break
    82  		case ErrorActionWarn:
    83  			Error.Printf("[file:%s line:%d]: %s", file, line, err.Error())
    84  			break
    85  		case ErrorActionDebug:
    86  			Error.Printf("[file:%s line:%d]: %s", file, line, err.Error())
    87  			break
    88  		case ErrorActionInfo:
    89  			Error.Printf("[file:%s line:%d]: %s", file, line, err.Error())
    90  			break
    91  		}
    92  	}
    93  	return (err != nil)
    94  }
    95  
    96  func WriteFile(filename string, source io.Reader) error {
    97  	writer, err := os.Create(filename)
    98  	if err != nil {
    99  		return err
   100  	}
   101  	defer writer.Close()
   102  	io.Copy(writer, source)
   103  	return nil
   104  }
   105  
   106  // This is neat: https://coderwall.com/p/cp5fya/measuring-execution-time-in-go
   107  func TimeTrack(start time.Time, name string) {
   108  	if Config.LogTimeTrack == true {
   109  		elapsed := time.Since(start)
   110  		Info.Printf("%s took %s", name, elapsed)
   111  	}
   112  }
   113  
   114  // pad str with padWith count times to right
   115  func PadRight(str string, padWith string, length int) string {
   116  	count := length - len(str)
   117  	if count < 0 {
   118  		count = 0
   119  	}
   120  	return str + strings.Repeat(padWith, count)
   121  }
   122  
   123  func InSlice(slice []string, searchFor string) (found bool) {
   124  	for _, v := range slice {
   125  		if searchFor == v {
   126  			found = true
   127  		}
   128  	}
   129  	return found
   130  }