/
errors.go
102 lines (91 loc) · 4.44 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package interop
import (
"net/http"
echo "github.com/labstack/echo/v4"
"go.thethings.network/lorawan-stack/pkg/errors"
)
var (
errUnknownMACVersion = errors.DefineInvalidArgument("unknown_mac_version", "unknown MAC version")
errInvalidLength = errors.DefineInvalidArgument("invalid_length", "invalid length")
errInvalidRequestType = errors.DefineInvalidArgument("invalid_request_type", "invalid request type `{type}`")
errNotRegistered = errors.DefineNotFound("not_registered", "not registered")
errUnexpectedResult = errors.Define("unexpected_result", "unexpected result code {code}", "code")
ErrNoAction = defineError("no_action", ResultNoAction, "no action")
ErrMIC = defineError("mic", ResultMICFailed, "MIC failed")
ErrFrameReplayed = defineError("frame_replayed", ResultFrameReplayed, "frame replayed")
ErrJoinReq = defineError("join_req", ResultJoinReqFailed, "join-request failed")
ErrNoRoamingAgreement = defineError("no_roaming_agreement", ResultNoRoamingAgreement, "no roaming agreement")
ErrDeviceRoaming = defineError("device_roaming", ResultDevRoamingDisallowed, "device roaming disallowed")
ErrRoamingActivation = defineError("roaming_activation", ResultRoamingActDisallowed, "roaming activation disallowed")
ErrActivation = defineError("activation", ResultActivationDisallowed, "activation disallowed")
ErrUnknownDevEUI = defineError("unknown_dev_eui", ResultUnknownDevEUI, "unknown DevEUI")
ErrUnknownDevAddr = defineError("unknown_dev_addr", ResultUnknownDevAddr, "unknown DevAddr")
ErrUnknownSender = defineError("unknown_sender", ResultUnknownSender, "unknown sender")
ErrUnknownReceiver = defineError("unknown_receiver", ResultUnknownReceiver, "unknown receiver")
ErrDeferred = defineError("deferred", ResultDeferred, "deferred")
ErrTransmitFailed = defineError("transmit_failed", ResultXmitFailed, "transmit failed")
ErrFPort = defineError("f_port", ResultInvalidFPort, "invalid FPort")
ErrProtocolVersion = defineError("protocol_version", ResultInvalidProtocolVersion, "invalid protocol version")
ErrStaleDeviceProfile = defineError("stale_device_profile", ResultStaleDeviceProfile, "stale device profile")
ErrMalformedMessage = defineError("malformed_message", ResultMalformedMessage, "malformed message")
ErrFrameSize = defineError("frame_size", ResultFrameSizeError, "frame size error")
)
var errorResults = make(map[string]ResultCode)
var resultErrors = make(map[ResultCode]errors.Definition)
func defineError(name string, result ResultCode, message string) errors.Definition {
definition := errors.DefineInvalidArgument(name, message)
errorResults[definition.FullName()] = result
resultErrors[result] = definition
return definition
}
type errorMessage struct {
Message string `json:"message"`
}
// ErrorHandler is an echo.HTTPErrorHandler.
func ErrorHandler(err error, c echo.Context) {
if httpErr, ok := err.(*echo.HTTPError); ok {
c.JSON(httpErr.Code, httpErr.Message)
return
}
result, statusCode, description := ResultOther, http.StatusInternalServerError, ""
if ttnErr, ok := errors.From(err); ok {
if val, ok := errorResults[ttnErr.FullName()]; ok {
result = val
if cause := errors.Cause(ttnErr); cause != nil && !errors.IsInternal(cause) {
description = cause.Error()
}
}
statusCode = errors.ToHTTPStatusCode(err)
}
if header, ok := c.Get(headerKey).(*RawMessageHeader); ok {
answerHeader, err := header.AnswerHeader()
if err != nil {
c.NoContent(http.StatusBadRequest)
} else {
c.JSON(statusCode, ErrorMessage{
RawMessageHeader: answerHeader,
Result: Result{
ResultCode: result,
Description: description,
},
})
}
} else if description != "" {
c.JSON(statusCode, errorMessage{description})
} else {
c.NoContent(statusCode)
}
}