fix: rest api errors (#919)

Co-authored-by: richΛrd <info@richardramos.me>
This commit is contained in:
Prem Chaitanya Prathi 2023-11-24 10:26:06 +05:30 committed by GitHub
parent b59a498606
commit d7249fc123
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 28 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/waku-org/go-waku/cmd/waku/server" "github.com/waku-org/go-waku/cmd/waku/server"
"github.com/waku-org/go-waku/waku/v2/node" "github.com/waku-org/go-waku/waku/v2/node"
"github.com/waku-org/go-waku/waku/v2/protocol" "github.com/waku-org/go-waku/waku/v2/protocol"
"github.com/waku-org/go-waku/waku/v2/protocol/pb"
"github.com/waku-org/go-waku/waku/v2/protocol/relay" "github.com/waku-org/go-waku/waku/v2/protocol/relay"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -56,6 +57,7 @@ func (r *RelayService) deleteV1Subscriptions(w http.ResponseWriter, req *http.Re
var topics []string var topics []string
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&topics); err != nil { if err := decoder.Decode(&topics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -76,6 +78,7 @@ func (r *RelayService) postV1Subscriptions(w http.ResponseWriter, req *http.Requ
var topics []string var topics []string
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&topics); err != nil { if err := decoder.Decode(&topics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -113,13 +116,14 @@ func (r *RelayService) postV1Subscriptions(w http.ResponseWriter, req *http.Requ
func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) { func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) {
topic := topicFromPath(w, req, "topic", r.log) topic := topicFromPath(w, req, "topic", r.log)
if topic == "" { if topic == "" {
return r.log.Debug("topic is not specified, using default waku topic")
topic = relay.DefaultWakuTopic
} }
//TODO: Update the API to also take a contentTopic since relay now supports filtering based on contentTopic as well. //TODO: Update the API to also take a contentTopic since relay now supports filtering based on contentTopic as well.
sub, err := r.node.Relay().GetSubscriptionWithPubsubTopic(topic, "") sub, err := r.node.Relay().GetSubscriptionWithPubsubTopic(topic, "")
if err != nil { if err != nil {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
_, err = w.Write([]byte("not subscribed to topic")) _, err = w.Write([]byte(err.Error()))
r.log.Error("writing response", zap.Error(err)) r.log.Error("writing response", zap.Error(err))
return return
} }
@ -160,28 +164,28 @@ func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) {
func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) { func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) {
topic := topicFromPath(w, req, "topic", r.log) topic := topicFromPath(w, req, "topic", r.log)
if topic == "" { if topic == "" {
return r.log.Debug("topic is not specified, using default waku topic")
topic = relay.DefaultWakuTopic
} }
var restMessage *RestWakuMessage var restMessage *RestWakuMessage
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&restMessage); err != nil { if err := decoder.Decode(&restMessage); err != nil {
w.WriteHeader(http.StatusBadRequest) r.log.Error("decoding request failure", zap.Error(err))
writeErrResponse(w, r.log, err, http.StatusBadRequest)
return return
} }
defer req.Body.Close() defer req.Body.Close()
if topic == "" {
topic = relay.DefaultWakuTopic
}
message, err := restMessage.ToProto() message, err := restMessage.ToProto()
if err != nil { if err != nil {
writeErrOrResponse(w, err, nil) r.log.Error("failed to convert message to proto", zap.Error(err))
writeErrResponse(w, r.log, err, http.StatusBadRequest)
return return
} }
if err := server.AppendRLNProof(r.node, message); err != nil { if err := server.AppendRLNProof(r.node, message); err != nil {
r.log.Error("failed to append RLN proof for the message", zap.Error(err))
writeErrOrResponse(w, err, nil) writeErrOrResponse(w, err, nil)
return return
} }
@ -189,6 +193,10 @@ func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) {
_, err = r.node.Relay().Publish(req.Context(), message, relay.WithPubSubTopic(strings.Replace(topic, "\n", "", -1))) _, err = r.node.Relay().Publish(req.Context(), message, relay.WithPubSubTopic(strings.Replace(topic, "\n", "", -1)))
if err != nil { if err != nil {
r.log.Error("publishing message", zap.Error(err)) r.log.Error("publishing message", zap.Error(err))
if err == pb.ErrMissingPayload || err == pb.ErrMissingContentTopic || err == pb.ErrInvalidMetaLength {
writeErrResponse(w, r.log, err, http.StatusBadRequest)
return
}
} }
writeErrOrResponse(w, err, true) writeErrOrResponse(w, err, true)
@ -198,6 +206,7 @@ func (r *RelayService) deleteV1AutoSubscriptions(w http.ResponseWriter, req *htt
var cTopics []string var cTopics []string
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&cTopics); err != nil { if err := decoder.Decode(&cTopics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -215,6 +224,7 @@ func (r *RelayService) postV1AutoSubscriptions(w http.ResponseWriter, req *http.
var cTopics []string var cTopics []string
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&cTopics); err != nil { if err := decoder.Decode(&cTopics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -225,11 +235,11 @@ func (r *RelayService) postV1AutoSubscriptions(w http.ResponseWriter, req *http.
if err != nil { if err != nil {
r.log.Error("subscribing to topics", zap.Strings("contentTopics", cTopics), zap.Error(err)) r.log.Error("subscribing to topics", zap.Strings("contentTopics", cTopics), zap.Error(err))
} }
r.log.Debug("subscribed to topics", zap.Strings("contentTopics", cTopics))
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest)
_, err := w.Write([]byte(err.Error()))
r.log.Error("writing response", zap.Error(err)) r.log.Error("writing response", zap.Error(err))
writeErrResponse(w, r.log, err, http.StatusBadRequest)
} else { } else {
writeErrOrResponse(w, err, true) writeErrOrResponse(w, err, true)
} }
@ -241,9 +251,8 @@ func (r *RelayService) getV1AutoMessages(w http.ResponseWriter, req *http.Reques
cTopic := topicFromPath(w, req, "contentTopic", r.log) cTopic := topicFromPath(w, req, "contentTopic", r.log)
sub, err := r.node.Relay().GetSubscription(cTopic) sub, err := r.node.Relay().GetSubscription(cTopic)
if err != nil { if err != nil {
w.WriteHeader(http.StatusNotFound)
_, err = w.Write([]byte("not subscribed to topic"))
r.log.Error("writing response", zap.Error(err)) r.log.Error("writing response", zap.Error(err))
writeErrResponse(w, r.log, err, http.StatusNotFound)
return return
} }
var response []*RestWakuMessage var response []*RestWakuMessage
@ -275,7 +284,7 @@ func (r *RelayService) postV1AutoMessage(w http.ResponseWriter, req *http.Reques
var restMessage *RestWakuMessage var restMessage *RestWakuMessage
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&restMessage); err != nil { if err := decoder.Decode(&restMessage); err != nil {
r.log.Error("decoding message failure", zap.Error(err)) r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
@ -295,12 +304,11 @@ func (r *RelayService) postV1AutoMessage(w http.ResponseWriter, req *http.Reques
_, err = r.node.Relay().Publish(req.Context(), message) _, err = r.node.Relay().Publish(req.Context(), message)
if err != nil { if err != nil {
r.log.Error("publishing message", zap.Error(err)) r.log.Error("publishing message", zap.Error(err))
} if err == pb.ErrMissingPayload || err == pb.ErrMissingContentTopic || err == pb.ErrInvalidMetaLength {
writeErrResponse(w, r.log, err, http.StatusBadRequest)
if err != nil { return
w.WriteHeader(http.StatusBadRequest) }
_, err := w.Write([]byte(err.Error())) writeErrResponse(w, r.log, err, http.StatusBadRequest)
r.log.Error("writing response", zap.Error(err))
} else { } else {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }

View File

@ -10,6 +10,16 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
// The functions writes error response in plain text format with specified statusCode
func writeErrResponse(w http.ResponseWriter, log *zap.Logger, err error, statusCode int) {
w.WriteHeader(statusCode)
_, err = w.Write([]byte(err.Error()))
if err != nil {
log.Error("error while writing response", zap.Error(err))
}
}
// This function writes error or response in json format with statusCode as 500 in case of error
func writeErrOrResponse(w http.ResponseWriter, err error, value interface{}) { func writeErrOrResponse(w http.ResponseWriter, err error, value interface{}) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.Header().Set("Content-Type", "application/json; charset=UTF-8")
@ -31,6 +41,7 @@ func writeErrOrResponse(w http.ResponseWriter, err error, value interface{}) {
} }
} }
// This function writes a response in json format
func writeResponse(w http.ResponseWriter, value interface{}, code int) { func writeResponse(w http.ResponseWriter, value interface{}, code int) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.Header().Set("Content-Type", "application/json; charset=UTF-8")
jsonResponse, err := json.Marshal(value) jsonResponse, err := json.Marshal(value)

View File

@ -7,22 +7,22 @@ import (
const MaxMetaAttrLength = 64 const MaxMetaAttrLength = 64
var ( var (
errMissingPayload = errors.New("missing Payload field") ErrMissingPayload = errors.New("missing Payload field")
errMissingContentTopic = errors.New("missing ContentTopic field") ErrMissingContentTopic = errors.New("missing ContentTopic field")
errInvalidMetaLength = errors.New("invalid length for Meta field") ErrInvalidMetaLength = errors.New("invalid length for Meta field")
) )
func (msg *WakuMessage) Validate() error { func (msg *WakuMessage) Validate() error {
if len(msg.Payload) == 0 { if len(msg.Payload) == 0 {
return errMissingPayload return ErrMissingPayload
} }
if msg.ContentTopic == "" { if msg.ContentTopic == "" {
return errMissingContentTopic return ErrMissingContentTopic
} }
if len(msg.Meta) > MaxMetaAttrLength { if len(msg.Meta) > MaxMetaAttrLength {
return errInvalidMetaLength return ErrInvalidMetaLength
} }
return nil return nil

View File

@ -327,8 +327,11 @@ func (w *WakuRelay) GetSubscriptionWithPubsubTopic(pubsubTopic string, contentTo
} else { } else {
contentFilter = waku_proto.NewContentFilter(pubsubTopic) contentFilter = waku_proto.NewContentFilter(pubsubTopic)
} }
sub, err := w.getSubscription(contentFilter)
return w.getSubscription(contentFilter) if err != nil {
err = errors.New("no subscription found for pubsubTopic")
}
return sub, err
} }
// GetSubscription fetches subscription matching a contentTopic(via autosharding) // GetSubscription fetches subscription matching a contentTopic(via autosharding)