code.vegaprotocol.io/vega@v0.79.0/datanode/api/errors_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package api_test
    17  
    18  import (
    19  	"errors"
    20  	"testing"
    21  
    22  	"code.vegaprotocol.io/vega/datanode/api"
    23  	"code.vegaprotocol.io/vega/datanode/entities"
    24  	types "code.vegaprotocol.io/vega/protos/vega"
    25  
    26  	"github.com/golang/protobuf/proto"
    27  	"github.com/stretchr/testify/assert"
    28  	"github.com/stretchr/testify/require"
    29  	"google.golang.org/grpc/codes"
    30  	"google.golang.org/grpc/status"
    31  )
    32  
    33  func TestErrorMapUniqueCodes(t *testing.T) {
    34  	errs := api.ErrorMap()
    35  	existing := map[int32]bool{}
    36  	for key, code := range errs {
    37  		if _, ok := existing[code]; ok {
    38  			t.Log("Duplicate code found in api.ErrorMap for code, duplicate =>", code, key)
    39  			t.Fail()
    40  			return
    41  		}
    42  		existing[code] = true
    43  	}
    44  }
    45  
    46  func Test_formatE(t *testing.T) {
    47  	type args struct {
    48  		err error
    49  		msg []error
    50  	}
    51  	tests := []struct {
    52  		name        string
    53  		args        args
    54  		wantErr     assert.ErrorAssertionFunc
    55  		wantCode    codes.Code
    56  		wantStr     string
    57  		wantMessage string
    58  		wantDetails proto.Message
    59  	}{
    60  		{
    61  			name: "nil error",
    62  			args: args{
    63  				err: nil,
    64  				msg: []error{},
    65  			},
    66  			wantErr: assert.NoError,
    67  		}, {
    68  			name: "internal error",
    69  			args: args{
    70  				err: api.ErrOrderServiceGetOrders,
    71  				msg: []error{errors.New("postgres has failed you")},
    72  			},
    73  			wantErr:     assert.Error,
    74  			wantStr:     "rpc error: code = Internal desc = Internal error",
    75  			wantCode:    codes.Internal,
    76  			wantMessage: "Internal error",
    77  			wantDetails: &types.ErrorDetail{
    78  				Code:    20007,
    79  				Message: "failed to get orders",
    80  				Inner:   "postgres has failed you",
    81  			},
    82  		}, {
    83  			name: "invalid arguments error",
    84  			args: args{
    85  				err: api.ErrMissingProposalID,
    86  			},
    87  			wantErr:     assert.Error,
    88  			wantStr:     "rpc error: code = InvalidArgument desc = InvalidArgument error",
    89  			wantCode:    codes.InvalidArgument,
    90  			wantMessage: "InvalidArgument error",
    91  			wantDetails: &types.ErrorDetail{
    92  				Code:    10021,
    93  				Message: "proposal id is a required parameter",
    94  			},
    95  		}, {
    96  			name: "not found error",
    97  			args: args{
    98  				err: api.ErrOrderNotFound,
    99  				msg: []error{entities.ErrNotFound},
   100  			},
   101  			wantErr:     assert.Error,
   102  			wantStr:     "rpc error: code = NotFound desc = NotFound error",
   103  			wantCode:    codes.NotFound,
   104  			wantMessage: "NotFound error",
   105  			wantDetails: &types.ErrorDetail{
   106  				Code:    20006,
   107  				Message: "order not found",
   108  				Inner:   "no resource corresponding to this id",
   109  			},
   110  		},
   111  	}
   112  	for _, tt := range tests {
   113  		t.Run(tt.name, func(t *testing.T) {
   114  			err := api.FormatE(tt.args.err, tt.args.msg...)
   115  			tt.wantErr(t, err, "formatE()")
   116  			if len(tt.wantStr) > 0 {
   117  				assert.EqualError(t, err, tt.wantStr, "formatE()")
   118  				s, ok := status.FromError(err)
   119  				assert.True(t, ok, "FromError()")
   120  				assert.Equal(t, tt.wantCode, s.Code(), "Code")
   121  				assert.Equal(t, tt.wantMessage, s.Message(), "Message")
   122  				require.Len(t, s.Details(), 1)
   123  				d, ok := s.Details()[0].(proto.Message)
   124  				require.True(t, ok)
   125  				if !proto.Equal(tt.wantDetails, d) {
   126  					t.Errorf("Details are not the same:\n\twant: %v\n\t got: %v", tt.wantDetails, d)
   127  				}
   128  			}
   129  		})
   130  	}
   131  }