mirror of
https://github.com/lightninglabs/loop
synced 2024-11-11 13:11:12 +00:00
Merge pull request #407 from carlaKC/355-surfaceloopingrpcerr
multi: surface grpc error codes from server to client
This commit is contained in:
commit
478f242f91
15
client.go
15
client.go
@ -15,6 +15,7 @@ import (
|
||||
"github.com/lightninglabs/loop/loopdb"
|
||||
"github.com/lightninglabs/loop/swap"
|
||||
"github.com/lightninglabs/loop/sweep"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -610,3 +611,17 @@ func (s *Client) LoopInTerms(ctx context.Context) (
|
||||
|
||||
return s.Server.GetLoopInTerms(ctx)
|
||||
}
|
||||
|
||||
// wrapGrpcError wraps the non-nil error provided with a message providing
|
||||
// additional context, preserving the grpc code returned with the original
|
||||
// error. If the original error has no grpc code, then codes.Unknown is used.
|
||||
func wrapGrpcError(message string, err error) error {
|
||||
// Since our error is non-nil, we don't need to worry about a nil
|
||||
// grpcStatus, we'll just get an unknown one if no code was passed back.
|
||||
grpcStatus, _ := status.FromError(err)
|
||||
|
||||
return status.Error(
|
||||
grpcStatus.Code(), fmt.Sprintf("%v: %v", message,
|
||||
grpcStatus.Message()),
|
||||
)
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -372,3 +374,39 @@ func testSuccess(ctx *testContext, amt btcutil.Amount, hash lntypes.Hash,
|
||||
|
||||
ctx.finish()
|
||||
}
|
||||
|
||||
// TestWrapGrpcError tests grpc error wrapping in the case where a grpc error
|
||||
// code is present, and when it is absent.
|
||||
func TestWrapGrpcError(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
original error
|
||||
expectedCode codes.Code
|
||||
}{
|
||||
{
|
||||
name: "out of range error",
|
||||
original: status.Error(
|
||||
codes.OutOfRange, "err string",
|
||||
),
|
||||
expectedCode: codes.OutOfRange,
|
||||
},
|
||||
{
|
||||
name: "no grpc code",
|
||||
original: errors.New("no error code"),
|
||||
expectedCode: codes.Unknown,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range tests {
|
||||
testCase := testCase
|
||||
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
err := wrapGrpcError("", testCase.original)
|
||||
require.Error(t, err, "test only expects errors")
|
||||
|
||||
status, ok := status.FromError(err)
|
||||
require.True(t, ok, "test expects grpc code")
|
||||
require.Equal(t, testCase.expectedCode, status.Code())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,10 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/mempool"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightninglabs/lndclient"
|
||||
"github.com/lightninglabs/loop/labels"
|
||||
"github.com/lightninglabs/loop/loopdb"
|
||||
@ -86,7 +85,7 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig,
|
||||
// request that we send to the server.
|
||||
quote, err := cfg.server.GetLoopInQuote(globalCtx, request.Amount)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loop in terms: %v", err)
|
||||
return nil, wrapGrpcError("loop in terms", err)
|
||||
}
|
||||
|
||||
swapFee := quote.SwapFee
|
||||
@ -172,7 +171,7 @@ func newLoopInSwap(globalCtx context.Context, cfg *swapConfig,
|
||||
)
|
||||
probeWaitCancel()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot initiate swap: %v", err)
|
||||
return nil, wrapGrpcError("cannot initiate swap", err)
|
||||
}
|
||||
|
||||
// Because the context is cancelled, it is guaranteed that we will be
|
||||
|
@ -4,15 +4,14 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightninglabs/loop/loopdb"
|
||||
"github.com/lightninglabs/loop/swap"
|
||||
"github.com/lightninglabs/loop/test"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -128,7 +128,7 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
|
||||
receiverKey, request.SwapPublicationDeadline, request.Initiator,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot initiate swap: %v", err)
|
||||
return nil, wrapGrpcError("cannot initiate swap", err)
|
||||
}
|
||||
|
||||
err = validateLoopOutContract(
|
||||
|
@ -19,3 +19,7 @@ This file tracks release notes for the loop client.
|
||||
#### Breaking Changes
|
||||
|
||||
#### Bug Fixes
|
||||
* Grpc error codes returned by the swap server when swap initiation fails are
|
||||
now surfaced to the client. Previously these error codes would be returned
|
||||
as a string.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user