mirror of
https://github.com/diamondburned/arikawa.git
synced 2024-11-19 21:32: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:
parent
101fe46313
commit
0d7774bd6a
|
@ -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":
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue