arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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}