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