functions.go 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Auxiliary functions which I'm always using.
  2. // Moved to separate file on 20211102.
  3. package main
  4. import (
  5. "fmt"
  6. "net/http"
  7. "path/filepath"
  8. "runtime"
  9. "github.com/google/uuid"
  10. // "github.com/op/go-logging"
  11. )
  12. // checkErrPanic logs a fatal error and panics.
  13. func checkErrPanic(err error) {
  14. if err != nil {
  15. if pc, file, line, ok := runtime.Caller(1); ok {
  16. log.Panicf("%s:%d (%v) - panic: %v\n", filepath.Base(file), line, pc, err)
  17. return
  18. }
  19. log.Panic(err)
  20. }
  21. }
  22. // checkErr checks if there is an error, and if yes, it logs it out and continues.
  23. //
  24. // this is for 'normal' situations when we want to get a log if something goes wrong but do not need to panic
  25. func checkErr(err error) {
  26. if err != nil {
  27. if pc, file, line, ok := runtime.Caller(1); ok {
  28. log.Errorf("%s:%d (%v) - error: %v\n", filepath.Base(file), line, pc, err)
  29. return
  30. }
  31. log.Panic(err)
  32. }
  33. }
  34. // Auxiliary functions for HTTP handling
  35. // checkErrHTTP returns an error via HTTP and also logs the error.
  36. func checkErrHTTP(w http.ResponseWriter, httpStatus int, errorMessage string, err error) {
  37. if err != nil {
  38. http.Error(w, fmt.Sprintf(errorMessage, err), httpStatus)
  39. if pc, file, line, ok := runtime.Caller(1); ok {
  40. log.Error("(", http.StatusText(httpStatus), ") ", filepath.Base(file), ":", line, ":", pc, " - error:", errorMessage, err)
  41. return
  42. }
  43. log.Error("(", http.StatusText(httpStatus), ") ", errorMessage, err)
  44. }
  45. }
  46. // checkErrPanicHTTP returns an error via HTTP and logs the error with a panic.
  47. func checkErrPanicHTTP(w http.ResponseWriter, httpStatus int, errorMessage string, err error) {
  48. if err != nil {
  49. http.Error(w, fmt.Sprintf(errorMessage, err), httpStatus)
  50. if pc, file, line, ok := runtime.Caller(1); ok {
  51. log.Panic("(", http.StatusText(httpStatus), ") ", filepath.Base(file), ":", line, ":", pc, " - panic:", errorMessage, err)
  52. return
  53. }
  54. log.Panic("(", http.StatusText(httpStatus), ") ", errorMessage, err)
  55. }
  56. }
  57. // logErrHTTP assumes that the error message was already composed and writes it to HTTP and logs it.
  58. //
  59. // this is mostly to avoid code duplication and make sure that all entries are written similarly
  60. func logErrHTTP(w http.ResponseWriter, httpStatus int, errorMessage string) {
  61. http.Error(w, errorMessage, httpStatus)
  62. log.Error("(" + http.StatusText(httpStatus) + ") " + errorMessage)
  63. }
  64. // funcName is @Sonia's solution to get the name of the function that Go is currently running.
  65. //
  66. // This will be extensively used to deal with figuring out where in the code the errors are!
  67. // Source: https://stackoverflow.com/a/10743805/1035977 (20170708)
  68. func funcName() string {
  69. if pc, _, _, ok := runtime.Caller(1); ok {
  70. return runtime.FuncForPC(pc).Name()
  71. }
  72. return ""
  73. }
  74. // isValidUUID returns whether the UUID is valid.
  75. // Thanks to Patrick D'Appollonio https://stackoverflow.com/questions/25051675/how-to-validate-uuid-v4-in-go
  76. // as well as https://stackoverflow.com/a/46315070/1035977 (gwyneth 29211031)
  77. // This exists mostly to be able to return just _one_ value (the boolean) and not require anything else.
  78. // Also note that _some_ UUIDs are not fully v4 compliant; LL invented a few ones for the first "special" residents
  79. func isValidUUID(u string) bool {
  80. _, err := uuid.Parse(u)
  81. return err == nil
  82. }