1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2025-01-05 03:37:08 +00:00

gateway: Skip unknown events while reconnecting (#255)

This change skips events that are unknown while the bot reconnects. This
is an event that is particularly rare as it requires unimplemented
events being called in the time before a bot's HELLO -> RESUME events
are called. This change explicitly returns unknown events as a special
time defined in wsutil/op.go and ignores them from reaching gateway/op.go
This commit is contained in:
Hamza Ali 2021-08-04 08:00:31 +07:00 committed by diamondburned
parent c780d474d4
commit 34a7c3ba2e
No known key found for this signature in database
GPG key ID: D78C4471CE776659
3 changed files with 30 additions and 5 deletions

View file

@ -534,7 +534,8 @@ func (g *Gateway) start(ctx context.Context) error {
// Expect either READY or RESUMED before continuing.
wsutil.WSDebug("Waiting for either READY or RESUMED.")
// WaitForEvent should
// WaitForEvent should until the bot becomes ready or resumes (if a
// previous ready event has already been called).
err := wsutil.WaitForEvent(ctx, g, ch, func(op *wsutil.OP) bool {
switch op.EventName {
case "READY":

View file

@ -85,10 +85,10 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error {
// Check if we know the event
fn, ok := EventCreator[op.EventName]
if !ok {
return fmt.Errorf(
"unknown event %s: %s",
op.EventName, string(op.Data),
)
return &wsutil.UnknownEventError{
Name: op.EventName,
Data: op.Data,
}
}
// Make a new pointer to the event

View file

@ -66,6 +66,25 @@ func AssertEvent(ev Event, code OPCode, v interface{}) (*OP, error) {
return op, nil
}
// UnknownEventError is required by HandleOP if an event is encountered that is
// not known. Internally, unknown events are logged and ignored. It is not a
// fatal error.
type UnknownEventError struct {
Name string
Data json.Raw
}
// Error formats the unknown event error to with the event name and payload
func (err UnknownEventError) Error() string {
return fmt.Sprintf("unknown event %s: %s", err.Name, string(err.Data))
}
// IsBrokenConnection returns true if the error is a broken connection error.
func IsUnknownEvent(err error) bool {
var uevent *UnknownEventError
return errors.As(err, &uevent)
}
type EventHandler interface {
HandleOP(op *OP) error
}
@ -98,6 +117,11 @@ func WaitForEvent(ctx context.Context, h EventHandler, ch <-chan Event, fn func(
// also prevent a race condition with things that need Ready after
// Open().
if err := h.HandleOP(o); err != nil {
// Explicitly ignore events we don't know.
if IsUnknownEvent(err) {
WSError(err)
continue
}
return err
}