Skip to content

Commit

Permalink
smarter error types
Browse files Browse the repository at this point in the history
  • Loading branch information
linkdata committed Oct 25, 2023
1 parent 53daaf1 commit 638619c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 19 deletions.
5 changes: 5 additions & 0 deletions errnowebsocketrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ func (e ErrNoWebSocketRequest) Error() string {
return fmt.Sprintf("no WebSocket request received from %v", e.Addr)
}

func (e ErrNoWebSocketRequest) Is(target error) (yes bool) {
_, yes = target.(ErrNoWebSocketRequest)
return
}

func newErrNoWebSocketRequest(rq *Request) error {
return ErrNoWebSocketRequest{Addr: rq.remoteIP}
}
36 changes: 36 additions & 0 deletions errpendingcancelled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package jaws

import (
"fmt"
)

type ErrPendingCancelled struct {
JawsKey uint64
Cause error
Initial string
}

func (e ErrPendingCancelled) Error() string {
return fmt.Sprintf("Request<%s>:%s %v", JawsKeyString(e.JawsKey), e.Initial, e.Cause)
}

func (e ErrPendingCancelled) Is(target error) (yes bool) {
_, yes = target.(ErrPendingCancelled)
return
}

func (e ErrPendingCancelled) Unwrap() error {
return e.Cause
}

func newErrPendingCancelled(rq *Request, cause error) (err error) {
var initial string
if rq.Initial != nil {
initial = fmt.Sprintf(" %s %q:", rq.Initial.Method, rq.Initial.RequestURI)
}
return ErrPendingCancelled{
JawsKey: rq.JawsKey,
Cause: cause,
Initial: initial,
}
}
23 changes: 7 additions & 16 deletions jaws.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,15 +549,14 @@ func (jw *Jaws) unsubscribe(msgCh chan Message) {
}
}

func errPendingCancelled(rq *Request, deadline time.Time) error {
err := context.Cause(rq.ctx)
if err == nil {
if rq.Created.After(deadline) {
return nil
}
func maybeErrPendingCancelled(rq *Request, deadline time.Time) (err error) {
if err = context.Cause(rq.ctx); err == nil && rq.Created.Before(deadline) {
err = newErrNoWebSocketRequest(rq)
}
return err
if err != nil {
err = newErrPendingCancelled(rq, err)
}
return
}

func (jw *Jaws) maintenance(requestTimeout time.Duration) {
Expand All @@ -567,17 +566,9 @@ func (jw *Jaws) maintenance(requestTimeout time.Duration) {
jw.mu.RLock()
now := time.Now()
deadline := now.Add(-requestTimeout)
logger := jw.Logger
for _, rq := range jw.pending {
if err := errPendingCancelled(rq, deadline); err != nil {
if err := jw.Log(maybeErrPendingCancelled(rq, deadline)); err != nil {
killReqs = append(killReqs, rq)
if logger != nil {
var uri string
if rq.Initial != nil {
uri = fmt.Sprintf("%s %q: ", rq.Initial.Method, rq.Initial.RequestURI)
}
logger.Printf("cancelled pending %v: %s%v", rq, uri, err)
}
}
}
for k, sess := range jw.sessions {
Expand Down
10 changes: 7 additions & 3 deletions jaws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,11 @@ func TestJaws_CleansUpUnconnected(t *testing.T) {
elem.SetInner("foo")
}
}
expectLen++
err := maybeErrPendingCancelled(rq, deadline)
if err == nil {
t.Fatal("expected error")
}
expectLen += len(err.Error() + "\n")
}
is.Equal(jw.Pending(), numReqs)

Expand All @@ -304,8 +308,8 @@ func TestJaws_CleansUpUnconnected(t *testing.T) {
case <-jw.Done():
}
w.Flush()
s := b.String()
if x := strings.Count(s, "\n"); x != expectLen {
if x := b.Len(); x != expectLen {
t.Log(b.String())
is.Equal(b.Len(), expectLen)
}
}
Expand Down
15 changes: 15 additions & 0 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -708,3 +708,18 @@ func TestRequest_IncomingClick(t *testing.T) {
default:
}
}

func TestRequest_CustomErrors(t *testing.T) {
is := testHelper{t}
rq := newTestRequest()
defer rq.Close()
cause := newErrNoWebSocketRequest(rq.Request)
err := newErrPendingCancelled(rq.Request, cause)
is.True(errors.Is(err, ErrPendingCancelled{}))
is.True(errors.Is(err, ErrNoWebSocketRequest{}))
is.Equal(errors.Is(cause, ErrPendingCancelled{}), false)
var target1 ErrNoWebSocketRequest
is.True(errors.As(err, &target1))
var target2 ErrPendingCancelled
is.Equal(errors.As(cause, &target2), false)
}

0 comments on commit 638619c

Please sign in to comment.