Skip to content

Commit

Permalink
don't swallow webhook processMsg status codes (#187)
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Shorsher <[email protected]>
  • Loading branch information
shorsher authored Dec 1, 2021
1 parent a115d6c commit 4372c21
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 11 deletions.
10 changes: 5 additions & 5 deletions internal/contractgateway/rest2eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import (
// REST2EthAsyncDispatcher is passed in to process messages over a streaming system with
// a receipt store. Only used for POST methods, when fly-sync is not set to true
type REST2EthAsyncDispatcher interface {
DispatchMsgAsync(ctx context.Context, msg map[string]interface{}, ack, immediateReceipt bool) (*messages.AsyncSentMsg, error)
DispatchMsgAsync(ctx context.Context, msg map[string]interface{}, ack, immediateReceipt bool) (*messages.AsyncSentMsg, int, error)
}

// rest2EthSyncDispatcher abstracts the processing of the transactions and queries
Expand Down Expand Up @@ -589,8 +589,8 @@ func (r *rest2eth) deployContract(res http.ResponseWriter, req *http.Request, fr
msgBytes, _ := json.Marshal(deployMsg)
var mapMsg map[string]interface{}
json.Unmarshal(msgBytes, &mapMsg)
if asyncResponse, err := r.asyncDispatcher.DispatchMsgAsync(req.Context(), mapMsg, ack, immediateReceipt); err != nil {
r.restErrReply(res, req, err, 500)
if asyncResponse, status, err := r.asyncDispatcher.DispatchMsgAsync(req.Context(), mapMsg, ack, immediateReceipt); err != nil {
r.restErrReply(res, req, err, status)
} else {
r.restAsyncReply(res, req, asyncResponse)
}
Expand Down Expand Up @@ -637,8 +637,8 @@ func (r *rest2eth) sendTransaction(res http.ResponseWriter, req *http.Request, f
msgBytes, _ := json.Marshal(msg)
var mapMsg map[string]interface{}
json.Unmarshal(msgBytes, &mapMsg)
if asyncResponse, err := r.asyncDispatcher.DispatchMsgAsync(req.Context(), mapMsg, ack, immediateReceipt); err != nil {
r.restErrReply(res, req, err, 500)
if asyncResponse, status, err := r.asyncDispatcher.DispatchMsgAsync(req.Context(), mapMsg, ack, immediateReceipt); err != nil {
r.restErrReply(res, req, err, status)
} else {
r.restAsyncReply(res, req, asyncResponse)
}
Expand Down
11 changes: 9 additions & 2 deletions internal/contractgateway/rest2eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type mockREST2EthDispatcher struct {
asyncDispatchAck bool
asyncDispatchReply *messages.AsyncSentMsg
asyncDispatchError error
asyncDispatchStatus int
sendTransactionMsg *messages.SendTransaction
sendTransactionSyncReceipt *messages.TransactionReceipt
sendTransactionSyncError error
Expand All @@ -55,10 +56,10 @@ type mockREST2EthDispatcher struct {
deployContractSyncError error
}

func (m *mockREST2EthDispatcher) DispatchMsgAsync(ctx context.Context, msg map[string]interface{}, ack, immediateReceipt bool) (*messages.AsyncSentMsg, error) {
func (m *mockREST2EthDispatcher) DispatchMsgAsync(ctx context.Context, msg map[string]interface{}, ack, immediateReceipt bool) (*messages.AsyncSentMsg, int, error) {
m.asyncDispatchMsg = msg
m.asyncDispatchAck = ack
return m.asyncDispatchReply, m.asyncDispatchError
return m.asyncDispatchReply, m.asyncDispatchStatus, m.asyncDispatchError
}

func (m *mockREST2EthDispatcher) DispatchSendTransactionSync(ctx context.Context, msg *messages.SendTransaction, replyProcessor rest2EthReplyProcessor) {
Expand Down Expand Up @@ -711,6 +712,7 @@ func TestDeployContractSyncRemoteRegistryGateway(t *testing.T) {
}
dispatcher := &mockREST2EthDispatcher{
sendTransactionSyncReceipt: receipt,
asyncDispatchStatus: 200,
}

r, router, res, _ := newTestREST2EthAndMsg(dispatcher, from, "", bodyMap)
Expand Down Expand Up @@ -744,6 +746,7 @@ func TestSendTransactionSyncFail(t *testing.T) {
from := "0x66c5fe653e7a9ebb628a6d40f0452d1e358baee8"
dispatcher := &mockREST2EthDispatcher{
sendTransactionSyncError: fmt.Errorf("pop"),
asyncDispatchStatus: 500,
}

r, router, res, req := newTestREST2EthAndMsg(dispatcher, from, to, bodyMap)
Expand Down Expand Up @@ -774,6 +777,7 @@ func TestSendTransactionAsyncFail(t *testing.T) {
from := "0x66c5fe653e7a9ebb628a6d40f0452d1e358baee8"
dispatcher := &mockREST2EthDispatcher{
asyncDispatchError: fmt.Errorf("pop"),
asyncDispatchStatus: 500,
}

r, router, res, req := newTestREST2EthAndMsg(dispatcher, from, to, bodyMap)
Expand Down Expand Up @@ -802,6 +806,7 @@ func TestDeployContractAsyncFail(t *testing.T) {
from := "0x66c5fe653e7a9ebb628a6d40f0452d1e358baee8"
dispatcher := &mockREST2EthDispatcher{
asyncDispatchError: fmt.Errorf("pop"),
asyncDispatchStatus: 500,
}

r, router, res, _ := newTestREST2EthAndMsg(dispatcher, from, "", bodyMap)
Expand Down Expand Up @@ -834,6 +839,7 @@ func TestSendTransactionAsyncBadMethod(t *testing.T) {
from := "0x66c5fe653e7a9ebb628a6d40f0452d1e358baee8"
dispatcher := &mockREST2EthDispatcher{
asyncDispatchError: fmt.Errorf("pop"),
asyncDispatchStatus: 500,
}

r, router, res, req := newTestREST2EthAndMsg(dispatcher, from, to, bodyMap)
Expand Down Expand Up @@ -862,6 +868,7 @@ func TestSendTransactionBadContract(t *testing.T) {
to := "badness"
from := "0x66c5fe653e7a9ebb628a6d40f0452d1e358baee8"
dispatcher := &mockREST2EthDispatcher{
asyncDispatchStatus: 500,
asyncDispatchError: fmt.Errorf("pop"),
}

Expand Down
6 changes: 3 additions & 3 deletions internal/rest/restgateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ func (g *RESTGateway) sendError(res http.ResponseWriter, msg string, code int) {
}

// DispatchMsgAsync is the rest2eth interface method for async dispatching of messages (via our webhook logic)
func (g *RESTGateway) DispatchMsgAsync(ctx context.Context, msg map[string]interface{}, ack, immediateReceipt bool) (*messages.AsyncSentMsg, error) {
reply, _, err := g.webhooks.processMsg(ctx, msg, ack, immediateReceipt)
return reply, err
func (g *RESTGateway) DispatchMsgAsync(ctx context.Context, msg map[string]interface{}, ack, immediateReceipt bool) (*messages.AsyncSentMsg, int, error) {
reply, status, err := g.webhooks.processMsg(ctx, msg, ack, immediateReceipt)
return reply, status, err
}

func (g *RESTGateway) newAccessTokenContextHandler(parent http.Handler) http.Handler {
Expand Down
3 changes: 2 additions & 1 deletion internal/rest/restgateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ func TestDispatchMsgAsyncPassesThroughToWebhooks(t *testing.T) {
g.webhooks = newWebhooks(fakeHandler, r, nil)

var fakeMsg map[string]interface{}
_, err := g.DispatchMsgAsync(context.Background(), fakeMsg, true, true)
_, status, err := g.DispatchMsgAsync(context.Background(), fakeMsg, true, true)
assert.Equal(400, status)
assert.Regexp("Invalid message - missing 'headers' \\(or not an object\\)", err)
}

0 comments on commit 4372c21

Please sign in to comment.