github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/util/server/error_test.go (about) 1 package server 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "net/http/httptest" 10 "testing" 11 12 "google.golang.org/grpc/codes" 13 "google.golang.org/grpc/status" 14 15 "github.com/prometheus/prometheus/promql" 16 "github.com/stretchr/testify/require" 17 "github.com/weaveworks/common/httpgrpc" 18 "github.com/weaveworks/common/user" 19 20 "github.com/grafana/loki/pkg/logqlmodel" 21 storage_errors "github.com/grafana/loki/pkg/storage/errors" 22 "github.com/grafana/loki/pkg/util" 23 ) 24 25 func Test_writeError(t *testing.T) { 26 for _, tt := range []struct { 27 name string 28 29 err error 30 msg string 31 expectedStatus int 32 }{ 33 {"cancelled", context.Canceled, ErrClientCanceled, StatusClientClosedRequest}, 34 {"cancelled multi", util.MultiError{context.Canceled, context.Canceled}, ErrClientCanceled, StatusClientClosedRequest}, 35 {"rpc cancelled", status.New(codes.Canceled, context.Canceled.Error()).Err(), "rpc error: code = Canceled desc = context canceled", http.StatusInternalServerError}, 36 {"rpc cancelled multi", util.MultiError{status.New(codes.Canceled, context.Canceled.Error()).Err(), status.New(codes.Canceled, context.Canceled.Error()).Err()}, "2 errors: rpc error: code = Canceled desc = context canceled; rpc error: code = Canceled desc = context canceled", http.StatusInternalServerError}, 37 {"mixed context and rpc cancelled", util.MultiError{context.Canceled, status.New(codes.Canceled, context.Canceled.Error()).Err()}, "2 errors: context canceled; rpc error: code = Canceled desc = context canceled", http.StatusInternalServerError}, 38 {"mixed context, rpc cancelled and another", util.MultiError{errors.New("standard error"), context.Canceled, status.New(codes.Canceled, context.Canceled.Error()).Err()}, "3 errors: standard error; context canceled; rpc error: code = Canceled desc = context canceled", http.StatusInternalServerError}, 39 {"cancelled storage", promql.ErrStorage{Err: context.Canceled}, ErrClientCanceled, StatusClientClosedRequest}, 40 {"orgid", user.ErrNoOrgID, user.ErrNoOrgID.Error(), http.StatusBadRequest}, 41 {"deadline", context.DeadlineExceeded, ErrDeadlineExceeded, http.StatusGatewayTimeout}, 42 {"deadline multi", util.MultiError{context.DeadlineExceeded, context.DeadlineExceeded}, ErrDeadlineExceeded, http.StatusGatewayTimeout}, 43 {"rpc deadline", status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()).Err(), ErrDeadlineExceeded, http.StatusGatewayTimeout}, 44 {"rpc deadline multi", util.MultiError{status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()).Err(), status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()).Err()}, ErrDeadlineExceeded, http.StatusGatewayTimeout}, 45 {"mixed context and rpc deadline", util.MultiError{context.DeadlineExceeded, status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()).Err()}, ErrDeadlineExceeded, http.StatusGatewayTimeout}, 46 {"mixed context, rpc deadline and another", util.MultiError{errors.New("standard error"), context.DeadlineExceeded, status.New(codes.DeadlineExceeded, context.DeadlineExceeded.Error()).Err()}, "3 errors: standard error; context deadline exceeded; rpc error: code = DeadlineExceeded desc = context deadline exceeded", http.StatusInternalServerError}, 47 {"parse error", logqlmodel.ParseError{}, "parse error : ", http.StatusBadRequest}, 48 {"httpgrpc", httpgrpc.Errorf(http.StatusBadRequest, errors.New("foo").Error()), "foo", http.StatusBadRequest}, 49 {"internal", errors.New("foo"), "foo", http.StatusInternalServerError}, 50 {"query error", storage_errors.ErrQueryMustContainMetricName, storage_errors.ErrQueryMustContainMetricName.Error(), http.StatusBadRequest}, 51 {"wrapped query error", fmt.Errorf("wrapped: %w", storage_errors.ErrQueryMustContainMetricName), "wrapped: " + storage_errors.ErrQueryMustContainMetricName.Error(), http.StatusBadRequest}, 52 {"multi mixed", util.MultiError{context.Canceled, context.DeadlineExceeded}, "2 errors: context canceled; context deadline exceeded", http.StatusInternalServerError}, 53 } { 54 t.Run(tt.name, func(t *testing.T) { 55 rec := httptest.NewRecorder() 56 WriteError(tt.err, rec) 57 require.Equal(t, tt.expectedStatus, rec.Result().StatusCode) 58 b, err := ioutil.ReadAll(rec.Result().Body) 59 if err != nil { 60 t.Fatal(err) 61 } 62 require.Equal(t, tt.msg, string(b[:len(b)-1])) 63 }) 64 } 65 }