1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-10-02 07:18:49 +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 GitHub
parent 101fe46313
commit 0d7774bd6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 5 deletions

View file

@ -474,7 +474,8 @@ func (g *Gateway) start(ctx context.Context) error {
// Expect either READY or RESUMED before continuing. // Expect either READY or RESUMED before continuing.
wsutil.WSDebug("Waiting for either READY or RESUMED.") 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 { err := wsutil.WaitForEvent(ctx, g, ch, func(op *wsutil.OP) bool {
switch op.EventName { switch op.EventName {
case "READY": case "READY":

View file

@ -85,10 +85,10 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error {
// Check if we know the event // Check if we know the event
fn, ok := EventCreator[op.EventName] fn, ok := EventCreator[op.EventName]
if !ok { if !ok {
return fmt.Errorf( return &wsutil.UnknownEventError{
"unknown event %s: %s", Name: op.EventName,
op.EventName, string(op.Data), Data: op.Data,
) }
} }
// Make a new pointer to the event // 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 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 { type EventHandler interface {
HandleOP(op *OP) error 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 // also prevent a race condition with things that need Ready after
// Open(). // Open().
if err := h.HandleOP(o); err != nil { if err := h.HandleOP(o); err != nil {
// Explicitly ignore events we don't know.
if IsUnknownEvent(err) {
WSError(err)
continue
}
return err return err
} }