Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: rest api errors #919

Merged
merged 8 commits into from
Nov 24, 2023
47 changes: 27 additions & 20 deletions cmd/waku/server/rest/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"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/protocol"
"github.com/waku-org/go-waku/waku/v2/protocol/pb"
"github.com/waku-org/go-waku/waku/v2/protocol/relay"
"go.uber.org/zap"
)
Expand Down Expand Up @@ -56,6 +57,7 @@ func (r *RelayService) deleteV1Subscriptions(w http.ResponseWriter, req *http.Re
var topics []string
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&topics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest)
return
}
Expand All @@ -76,6 +78,7 @@ func (r *RelayService) postV1Subscriptions(w http.ResponseWriter, req *http.Requ
var topics []string
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&topics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest)
return
}
Expand Down Expand Up @@ -113,13 +116,13 @@ func (r *RelayService) postV1Subscriptions(w http.ResponseWriter, req *http.Requ
func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) {
topic := topicFromPath(w, req, "topic", r.log)
if topic == "" {
return
topic = relay.DefaultWakuTopic
chaitanyaprem marked this conversation as resolved.
Show resolved Hide resolved
}
//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, "")
if err != nil {
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))
return
}
Expand Down Expand Up @@ -160,35 +163,39 @@ func (r *RelayService) getV1Messages(w http.ResponseWriter, req *http.Request) {
func (r *RelayService) postV1Message(w http.ResponseWriter, req *http.Request) {
topic := topicFromPath(w, req, "topic", r.log)
if topic == "" {
return
r.log.Debug("topic is not specified,using default waku topic")
chaitanyaprem marked this conversation as resolved.
Show resolved Hide resolved
topic = relay.DefaultWakuTopic
}

var restMessage *RestWakuMessage
decoder := json.NewDecoder(req.Body)
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
}
defer req.Body.Close()

if topic == "" {
topic = relay.DefaultWakuTopic
}

message, err := restMessage.ToProto()
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
}

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)
return
}

_, err = r.node.Relay().Publish(req.Context(), message, relay.WithPubSubTopic(strings.Replace(topic, "\n", "", -1)))
if err != nil {
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)
Expand All @@ -198,6 +205,7 @@ func (r *RelayService) deleteV1AutoSubscriptions(w http.ResponseWriter, req *htt
var cTopics []string
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&cTopics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest)
return
}
Expand All @@ -215,6 +223,7 @@ func (r *RelayService) postV1AutoSubscriptions(w http.ResponseWriter, req *http.
var cTopics []string
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&cTopics); err != nil {
r.log.Error("decoding request failure", zap.Error(err))
w.WriteHeader(http.StatusBadRequest)
return
}
Expand All @@ -225,11 +234,11 @@ func (r *RelayService) postV1AutoSubscriptions(w http.ResponseWriter, req *http.
if err != nil {
r.log.Error("subscribing to topics", zap.Strings("contentTopics", cTopics), zap.Error(err))
}
r.log.Debug("subscribed to topics", zap.Strings("contentTopics", cTopics))
Dismissed Show dismissed Hide dismissed

if err != nil {
w.WriteHeader(http.StatusBadRequest)
_, err := w.Write([]byte(err.Error()))
r.log.Error("writing response", zap.Error(err))
writeErrResponse(w, r.log, err, http.StatusBadRequest)
} else {
writeErrOrResponse(w, err, true)
}
Expand All @@ -241,9 +250,8 @@ func (r *RelayService) getV1AutoMessages(w http.ResponseWriter, req *http.Reques
cTopic := topicFromPath(w, req, "contentTopic", r.log)
sub, err := r.node.Relay().GetSubscription(cTopic)
if err != nil {
w.WriteHeader(http.StatusNotFound)
_, err = w.Write([]byte("not subscribed to topic"))
r.log.Error("writing response", zap.Error(err))
writeErrResponse(w, r.log, err, http.StatusNotFound)
return
}
var response []*RestWakuMessage
Expand Down Expand Up @@ -275,7 +283,7 @@ func (r *RelayService) postV1AutoMessage(w http.ResponseWriter, req *http.Reques
var restMessage *RestWakuMessage
decoder := json.NewDecoder(req.Body)
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)
return
}
Expand All @@ -295,12 +303,11 @@ func (r *RelayService) postV1AutoMessage(w http.ResponseWriter, req *http.Reques
_, err = r.node.Relay().Publish(req.Context(), message)
if err != nil {
r.log.Error("publishing message", zap.Error(err))
}

if err != nil {
w.WriteHeader(http.StatusBadRequest)
_, err := w.Write([]byte(err.Error()))
r.log.Error("writing response", zap.Error(err))
if err == pb.ErrMissingPayload || err == pb.ErrMissingContentTopic || err == pb.ErrInvalidMetaLength {
writeErrResponse(w, r.log, err, http.StatusBadRequest)
return
}
writeErrResponse(w, r.log, err, http.StatusBadRequest)
} else {
w.WriteHeader(http.StatusOK)
}
Expand Down
11 changes: 11 additions & 0 deletions cmd/waku/server/rest/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ import (
"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{}) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")

Expand All @@ -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) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
jsonResponse, err := json.Marshal(value)
Expand Down
12 changes: 6 additions & 6 deletions waku/v2/protocol/pb/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ import (
const MaxMetaAttrLength = 64

var (
errMissingPayload = errors.New("missing Payload field")
errMissingContentTopic = errors.New("missing ContentTopic field")
errInvalidMetaLength = errors.New("invalid length for Meta field")
ErrMissingPayload = errors.New("missing Payload field")
ErrMissingContentTopic = errors.New("missing ContentTopic field")
ErrInvalidMetaLength = errors.New("invalid length for Meta field")
)

func (msg *WakuMessage) Validate() error {
if len(msg.Payload) == 0 {
return errMissingPayload
return ErrMissingPayload
}

if msg.ContentTopic == "" {
return errMissingContentTopic
return ErrMissingContentTopic
}

if len(msg.Meta) > MaxMetaAttrLength {
return errInvalidMetaLength
return ErrInvalidMetaLength
}

return nil
Expand Down
7 changes: 5 additions & 2 deletions waku/v2/protocol/relay/waku_relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,11 @@ func (w *WakuRelay) GetSubscriptionWithPubsubTopic(pubsubTopic string, contentTo
} else {
contentFilter = waku_proto.NewContentFilter(pubsubTopic)
}

return w.getSubscription(contentFilter)
sub, err := 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)
Expand Down