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:
parent
c780d474d4
commit
34a7c3ba2e
|
@ -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":
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue