Skip to content

Commit

Permalink
Rename AsyncSignalError to PollingSignalError
Browse files Browse the repository at this point in the history
...and use it everywhere
  • Loading branch information
onsi committed Oct 26, 2022
1 parent abd25f0 commit d63d67e
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 130 deletions.
5 changes: 5 additions & 0 deletions gomega_dsl.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,11 @@ When `TryAgainAfter(<duration>` is triggered `Eventually` and `Consistently` wil
*/
var TryAgainAfter = internal.TryAgainAfter

/*
PollingSignalError is the error returned by StopTrying() and TryAgainAfter()
*/
type PollingSignalError = internal.PollingSignalError

// SetDefaultEventuallyTimeout sets the default timeout duration for Eventually. Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses.
func SetDefaultEventuallyTimeout(t time.Duration) {
Default.SetDefaultEventuallyTimeout(t)
Expand Down
23 changes: 11 additions & 12 deletions internal/async_assertion.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (assertion *AsyncAssertion) processReturnValues(values []reflect.Value) (in
}

actual := values[0].Interface()
if _, ok := AsAsyncSignalError(actual); ok {
if _, ok := AsPollingSignalError(actual); ok {
return actual, actual.(error)
}

Expand All @@ -144,7 +144,7 @@ func (assertion *AsyncAssertion) processReturnValues(values []reflect.Value) (in
if extra == nil {
continue
}
if _, ok := AsAsyncSignalError(extra); ok {
if _, ok := AsPollingSignalError(extra); ok {
return actual, extra.(error)
}
extraType := reflect.TypeOf(extra)
Expand Down Expand Up @@ -253,13 +253,13 @@ func (assertion *AsyncAssertion) buildActualPoller() (func() (interface{}, error
actual = assertionFailure
} else {
actual, err = assertion.processReturnValues(values)
_, isAsyncError := AsAsyncSignalError(err)
_, isAsyncError := AsPollingSignalError(err)
if assertionFailure != nil && !isAsyncError {
err = assertionFailure
}
}
if e := recover(); e != nil {
if _, isAsyncError := AsAsyncSignalError(e); isAsyncError {
if _, isAsyncError := AsPollingSignalError(e); isAsyncError {
err = e.(error)
} else if assertionFailure == nil {
panic(e)
Expand Down Expand Up @@ -308,7 +308,7 @@ func (assertion *AsyncAssertion) matcherSaysStopTrying(matcher types.GomegaMatch
func (assertion *AsyncAssertion) pollMatcher(matcher types.GomegaMatcher, value interface{}) (matches bool, err error) {
defer func() {
if e := recover(); e != nil {
if _, isAsyncError := AsAsyncSignalError(e); isAsyncError {
if _, isAsyncError := AsPollingSignalError(e); isAsyncError {
err = e.(error)
} else {
panic(e)
Expand Down Expand Up @@ -350,10 +350,9 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
defer lock.Unlock()
message := ""
if err != nil {
//TODO - formatting for TryAgainAfter?
if asyncSignal, ok := AsAsyncSignalError(err); ok && asyncSignal.IsStopTrying() {
if pollingSignalErr, ok := AsPollingSignalError(err); ok && pollingSignalErr.IsStopTrying() {
message = err.Error()
for _, attachment := range asyncSignal.Attachments {
for _, attachment := range pollingSignalErr.Attachments {
message += fmt.Sprintf("\n%s:\n", attachment.Description)
message += format.Object(attachment.Object, 1)
}
Expand Down Expand Up @@ -389,13 +388,13 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch
var nextPoll <-chan time.Time = nil
var isTryAgainAfterError = false

if asyncSignal, ok := AsAsyncSignalError(err); ok {
if asyncSignal.IsStopTrying() {
if pollingSignalErr, ok := AsPollingSignalError(err); ok {
if pollingSignalErr.IsStopTrying() {
fail("Told to stop trying")
return false
}
if asyncSignal.IsTryAgainAfter() {
nextPoll = time.After(asyncSignal.TryAgainDuration())
if pollingSignalErr.IsTryAgainAfter() {
nextPoll = time.After(pollingSignalErr.TryAgainDuration())
isTryAgainAfterError = true
}
}
Expand Down
1 change: 0 additions & 1 deletion internal/async_assertion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1448,7 +1448,6 @@ sprocket:
ig.G.Eventually(42).Should(HaveLen(1), "foo", ContainElement(42))
}).NotTo(Panic())
})

})

Context("eventual nil-ism", func() { // issue #555
Expand Down
107 changes: 0 additions & 107 deletions internal/async_signal_error.go

This file was deleted.

106 changes: 106 additions & 0 deletions internal/polling_signal_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package internal

import (
"errors"
"fmt"
"time"
)

type PollingSignalErrorType int

const (
PollingSignalErrorTypeStopTrying PollingSignalErrorType = iota
PollingSignalErrorTypeTryAgainAfter
)

type PollingSignalError interface {
error
Wrap(err error) PollingSignalError
Attach(description string, obj any) PollingSignalError
Now()
}

var StopTrying = func(message string) PollingSignalError {
return &PollingSignalErrorImpl{
message: message,
pollingSignalErrorType: PollingSignalErrorTypeStopTrying,
}
}

var TryAgainAfter = func(duration time.Duration) PollingSignalError {
return &PollingSignalErrorImpl{
message: fmt.Sprintf("told to try again after %s", duration),
duration: duration,
pollingSignalErrorType: PollingSignalErrorTypeTryAgainAfter,
}
}

type PollingSignalErrorAttachment struct {
Description string
Object any
}

type PollingSignalErrorImpl struct {
message string
wrappedErr error
pollingSignalErrorType PollingSignalErrorType
duration time.Duration
Attachments []PollingSignalErrorAttachment
}

func (s *PollingSignalErrorImpl) Wrap(err error) PollingSignalError {
s.wrappedErr = err
return s
}

func (s *PollingSignalErrorImpl) Attach(description string, obj any) PollingSignalError {
s.Attachments = append(s.Attachments, PollingSignalErrorAttachment{description, obj})
return s
}

func (s *PollingSignalErrorImpl) Error() string {
if s.wrappedErr == nil {
return s.message
} else {
return s.message + ": " + s.wrappedErr.Error()
}
}

func (s *PollingSignalErrorImpl) Unwrap() error {
if s == nil {
return nil
}
return s.wrappedErr
}

func (s *PollingSignalErrorImpl) Now() {
panic(s)
}

func (s *PollingSignalErrorImpl) IsStopTrying() bool {
return s.pollingSignalErrorType == PollingSignalErrorTypeStopTrying
}

func (s *PollingSignalErrorImpl) IsTryAgainAfter() bool {
return s.pollingSignalErrorType == PollingSignalErrorTypeTryAgainAfter
}

func (s *PollingSignalErrorImpl) TryAgainDuration() time.Duration {
return s.duration
}

func AsPollingSignalError(actual interface{}) (*PollingSignalErrorImpl, bool) {
if actual == nil {
return nil, false
}
if actualErr, ok := actual.(error); ok {
var target *PollingSignalErrorImpl
if errors.As(actualErr, &target) {
return target, true
} else {
return nil, false
}
}

return nil, false
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
"github.com/onsi/gomega/internal"
)

var _ = Describe("AsyncSignalError", func() {
var _ = Describe("PollingSignalError", func() {
Describe("StopTrying", func() {
Describe("building StopTrying errors", func() {
It("returns a correctly configured StopTrying error", func() {
st := StopTrying("I've tried 17 times - give up!")
Ω(st.Error()).Should(Equal("I've tried 17 times - give up!"))
Ω(errors.Unwrap(st)).Should(BeNil())
Ω(st.(*internal.AsyncSignalErrorImpl).IsStopTrying()).Should(BeTrue())
Ω(st.(*internal.PollingSignalErrorImpl).IsStopTrying()).Should(BeTrue())
})
})

Expand All @@ -32,35 +32,35 @@ var _ = Describe("AsyncSignalError", func() {

Describe("When attaching objects", func() {
It("attaches them, with their descriptions", func() {
st := StopTrying("Welp!").Attach("Max retries attained", 17).Attach("Got this response", "FLOOP").(*internal.AsyncSignalErrorImpl)
st := StopTrying("Welp!").Attach("Max retries attained", 17).Attach("Got this response", "FLOOP").(*internal.PollingSignalErrorImpl)
Ω(st.Attachments).Should(HaveLen(2))
Ω(st.Attachments[0]).Should(Equal(internal.AsyncSignalErrorAttachment{"Max retries attained", 17}))
Ω(st.Attachments[1]).Should(Equal(internal.AsyncSignalErrorAttachment{"Got this response", "FLOOP"}))
Ω(st.Attachments[0]).Should(Equal(internal.PollingSignalErrorAttachment{"Max retries attained", 17}))
Ω(st.Attachments[1]).Should(Equal(internal.PollingSignalErrorAttachment{"Got this response", "FLOOP"}))
})
})

Describe("when invoking Now()", func() {
It("should panic with itself", func() {
st := StopTrying("bam").(*internal.AsyncSignalErrorImpl)
st := StopTrying("bam").(*internal.PollingSignalErrorImpl)
Ω(st.Now).Should(PanicWith(st))
})
})

Describe("AsAsyncSignalError", func() {
Describe("AsPollingSignalError", func() {
It("should return false for nils", func() {
st, ok := internal.AsAsyncSignalError(nil)
st, ok := internal.AsPollingSignalError(nil)
Ω(st).Should(BeNil())
Ω(ok).Should(BeFalse())
})

It("should work when passed a StopTrying error", func() {
st, ok := internal.AsAsyncSignalError(StopTrying("bam"))
st, ok := internal.AsPollingSignalError(StopTrying("bam"))
Ω(st).Should(Equal(StopTrying("bam")))
Ω(ok).Should(BeTrue())
})

It("should work when passed a wrapped error", func() {
st, ok := internal.AsAsyncSignalError(fmt.Errorf("STOP TRYING %w", StopTrying("bam")))
st, ok := internal.AsPollingSignalError(fmt.Errorf("STOP TRYING %w", StopTrying("bam")))
Ω(st).Should(Equal(StopTrying("bam")))
Ω(ok).Should(BeTrue())
})
Expand Down

0 comments on commit d63d67e

Please sign in to comment.