You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.4 KiB

  1. package api
  2. import (
  3. "database/sql"
  4. "errors"
  5. "net/http"
  6. "github.com/gin-gonic/gin"
  7. "github.com/hermeznetwork/hermez-node/db/historydb"
  8. "github.com/hermeznetwork/hermez-node/log"
  9. "github.com/hermeznetwork/hermez-node/metric"
  10. "github.com/hermeznetwork/tracerr"
  11. "github.com/lib/pq"
  12. "github.com/russross/meddler"
  13. )
  14. const (
  15. // maxLimit is the max permitted items to be returned in paginated responses
  16. maxLimit uint = 2049
  17. // dfltOrder indicates how paginated endpoints are ordered if not specified
  18. dfltOrder = historydb.OrderAsc
  19. // dfltLimit indicates the limit of returned items in paginated responses if the query param limit is not provided
  20. dfltLimit uint = 20
  21. // 2^32 -1
  22. maxUint32 = 4294967295
  23. // 2^64 /2 -1
  24. maxInt64 = 9223372036854775807
  25. // Error for duplicated key
  26. errDuplicatedKey = "Item already exists"
  27. // Error for timeout due to SQL connection
  28. errSQLTimeout = "The node is under heavy preasure, please try again later"
  29. // Error message returned when context reaches timeout
  30. errCtxTimeout = "context deadline exceeded"
  31. )
  32. var (
  33. // ErrNilBidderAddr is used when a nil bidderAddr is received in the getCoordinator method
  34. ErrNilBidderAddr = errors.New("biderAddr can not be nil")
  35. )
  36. func retSQLErr(err error, c *gin.Context) {
  37. log.Warnw("HTTP API SQL request error", "err", err)
  38. unwrapErr := tracerr.Unwrap(err)
  39. metric.CollectError(unwrapErr)
  40. errMsg := unwrapErr.Error()
  41. retDupKey := func(errCode pq.ErrorCode) {
  42. // https://www.postgresql.org/docs/current/errcodes-appendix.html
  43. if errCode == "23505" {
  44. c.JSON(http.StatusInternalServerError, errorMsg{
  45. Message: errDuplicatedKey,
  46. })
  47. } else {
  48. c.JSON(http.StatusInternalServerError, errorMsg{
  49. Message: errMsg,
  50. })
  51. }
  52. }
  53. if errMsg == errCtxTimeout {
  54. c.JSON(http.StatusServiceUnavailable, errorMsg{
  55. Message: errSQLTimeout,
  56. })
  57. } else if sqlErr, ok := tracerr.Unwrap(err).(*pq.Error); ok {
  58. retDupKey(sqlErr.Code)
  59. } else if sqlErr, ok := meddler.DriverErr(tracerr.Unwrap(err)); ok {
  60. retDupKey(sqlErr.(*pq.Error).Code)
  61. } else if tracerr.Unwrap(err) == sql.ErrNoRows {
  62. c.JSON(http.StatusNotFound, errorMsg{
  63. Message: errMsg,
  64. })
  65. } else {
  66. c.JSON(http.StatusInternalServerError, errorMsg{
  67. Message: errMsg,
  68. })
  69. }
  70. }
  71. func retBadReq(err error, c *gin.Context) {
  72. log.Warnw("HTTP API Bad request error", "err", err)
  73. metric.CollectError(err)
  74. c.JSON(http.StatusBadRequest, errorMsg{
  75. Message: err.Error(),
  76. })
  77. }