errors.go 2.45 KB
Newer Older
1
package helpers
2
3

import (
4
5
	"reflect"

6
7
8
	"github.com/pkg/errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
9
	"google.golang.org/grpc/status"
10

11
12
13
	"github.com/brocaar/chirpstack-application-server/internal/integration/http"
	"github.com/brocaar/chirpstack-application-server/internal/integration/influxdb"
	"github.com/brocaar/chirpstack-application-server/internal/storage"
14
15
16
)

var errToCode = map[error]codes.Code{
17
18
19
20
21
22
23
24
25
26
27
28
	storage.ErrAlreadyExists:                   codes.AlreadyExists,
	storage.ErrDoesNotExist:                    codes.NotFound,
	storage.ErrUsedByOtherObjects:              codes.FailedPrecondition,
	storage.ErrApplicationInvalidName:          codes.InvalidArgument,
	storage.ErrNodeInvalidName:                 codes.InvalidArgument,
	storage.ErrNodeMaxRXDelay:                  codes.InvalidArgument,
	storage.ErrCFListTooManyChannels:           codes.InvalidArgument,
	storage.ErrUserInvalidUsername:             codes.InvalidArgument,
	storage.ErrUserPasswordLength:              codes.InvalidArgument,
	storage.ErrInvalidUsernameOrPassword:       codes.Unauthenticated,
	storage.ErrInvalidEmail:                    codes.InvalidArgument,
	storage.ErrInvalidGatewayDiscoveryInterval: codes.InvalidArgument,
29
	storage.ErrDeviceProfileInvalidName:        codes.InvalidArgument,
30
	storage.ErrServiceProfileInvalidName:       codes.InvalidArgument,
31
	storage.ErrMulticastGroupInvalidName:       codes.InvalidArgument,
32
33
	storage.ErrOrganizationMaxDeviceCount:      codes.FailedPrecondition,
	storage.ErrOrganizationMaxGatewayCount:     codes.FailedPrecondition,
34
	storage.ErrNetworkServerInvalidName:        codes.InvalidArgument,
35
	storage.ErrAPIKeyInvalidName:               codes.InvalidArgument,
36
37
	http.ErrInvalidHeaderName:                  codes.InvalidArgument,
	influxdb.ErrInvalidPrecision:               codes.InvalidArgument,
38
39
}

40
// ErrToRPCError converts the given error into a gRPC error.
41
func ErrToRPCError(err error) error {
42
	cause := errors.Cause(err)
43
44
45
46
47
48
49

	// if the err has already a gRPC status (it is a gRPC error), just
	// return the error.
	if code := status.Code(cause); code != codes.Unknown {
		return cause
	}

50
51
52
53
54
55
56
	// Some error values (error returned by Otto) can not be hashed:
	// https://github.com/brocaar/chirpstack-application-server/issues/631
	k := reflect.TypeOf(cause).Kind()
	if k == reflect.Slice {
		return grpc.Errorf(codes.Unknown, cause.Error())
	}

57
58
59
60
61
62
	code, ok := errToCode[cause]
	if !ok {
		code = codes.Unknown
	}
	return grpc.Errorf(code, cause.Error())
}