Skip to content

Commit e6dce57

Browse files
authored
Use SIP statuses as Go and gRPC errors. (#960)
1 parent bdefe90 commit e6dce57

File tree

3 files changed

+79
-1
lines changed

3 files changed

+79
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"github.com/livekit/protocol": minor
3+
---
4+
5+
Use SIP statuses as Go and gRPC errors.

livekit/sip.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,67 @@ import (
88
"strconv"
99
"strings"
1010

11+
"google.golang.org/grpc/codes"
12+
"google.golang.org/grpc/status"
13+
1114
"github.com/livekit/protocol/utils/xtwirp"
1215
)
1316

14-
var _ xtwirp.ErrorMeta = (*SIPStatus)(nil)
17+
var (
18+
_ xtwirp.ErrorMeta = (*SIPStatus)(nil)
19+
_ error = (*SIPStatus)(nil)
20+
)
21+
22+
func (p SIPStatusCode) ShortName() string {
23+
return strings.TrimPrefix(p.String(), "SIP_STATUS_")
24+
}
25+
26+
func (p *SIPStatus) Error() string {
27+
if p.Status != "" {
28+
return fmt.Sprintf("sip status: %d: %s", p.Code, p.Status)
29+
}
30+
return fmt.Sprintf("sip status: %d (%s)", p.Code, p.Code.ShortName())
31+
}
32+
33+
func (p *SIPStatus) GRPCStatus() *status.Status {
34+
msg := p.Status
35+
if msg == "" {
36+
msg = p.Code.ShortName()
37+
}
38+
var code = codes.Internal
39+
switch p.Code {
40+
case SIPStatusCode_SIP_STATUS_OK:
41+
return status.New(codes.OK, "OK")
42+
case SIPStatusCode_SIP_STATUS_REQUEST_TERMINATED:
43+
code = codes.Aborted
44+
case SIPStatusCode_SIP_STATUS_BAD_REQUEST,
45+
SIPStatusCode_SIP_STATUS_NOTFOUND,
46+
SIPStatusCode_SIP_STATUS_ADDRESS_INCOMPLETE,
47+
SIPStatusCode_SIP_STATUS_AMBIGUOUS,
48+
SIPStatusCode_SIP_STATUS_BAD_EXTENSION,
49+
SIPStatusCode_SIP_STATUS_EXTENSION_REQUIRED:
50+
code = codes.InvalidArgument
51+
case SIPStatusCode_SIP_STATUS_REQUEST_TIMEOUT,
52+
SIPStatusCode_SIP_STATUS_GATEWAY_TIMEOUT:
53+
code = codes.DeadlineExceeded
54+
case SIPStatusCode_SIP_STATUS_SERVICE_UNAVAILABLE,
55+
SIPStatusCode_SIP_STATUS_TEMPORARILY_UNAVAILABLE,
56+
SIPStatusCode_SIP_STATUS_BUSY_HERE,
57+
SIPStatusCode_SIP_STATUS_GLOBAL_BUSY_EVERYWHERE,
58+
SIPStatusCode_SIP_STATUS_NOT_IMPLEMENTED,
59+
SIPStatusCode_SIP_STATUS_GLOBAL_DECLINE:
60+
code = codes.Unavailable
61+
case SIPStatusCode_SIP_STATUS_PROXY_AUTH_REQUIRED,
62+
SIPStatusCode_SIP_STATUS_UNAUTHORIZED,
63+
SIPStatusCode_SIP_STATUS_FORBIDDEN:
64+
code = codes.PermissionDenied
65+
}
66+
st := status.New(code, fmt.Sprintf("sip status %d: %s", p.Code, msg))
67+
if st2, err := st.WithDetails(p); err == nil {
68+
return st2
69+
}
70+
return st
71+
}
1572

1673
func (p *SIPStatus) TwirpErrorMeta() map[string]string {
1774
status := p.Status

livekit/sip_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import (
55
"testing"
66

77
"github.com/stretchr/testify/require"
8+
"google.golang.org/grpc/codes"
9+
"google.golang.org/grpc/status"
10+
"google.golang.org/protobuf/proto"
811
)
912

1013
func TestSIPTrunkAs(t *testing.T) {
@@ -358,3 +361,16 @@ func TestSIPDispatchRuleFilter(t *testing.T) {
358361
})
359362
}
360363
}
364+
365+
func TestGRPCStatus(t *testing.T) {
366+
e := &SIPStatus{Code: SIPStatusCode_SIP_STATUS_BUSY_HERE}
367+
st, ok := status.FromError(e)
368+
require.True(t, ok)
369+
require.Equal(t, codes.Unavailable, st.Code())
370+
require.Equal(t, "sip status 486: BUSY_HERE", st.Message())
371+
details := st.Details()
372+
require.Len(t, details, 1)
373+
e2, ok := details[0].(*SIPStatus)
374+
require.True(t, ok)
375+
require.True(t, proto.Equal(e, e2))
376+
}

0 commit comments

Comments
 (0)