+43
-4
@@ -54,6 +54,12 @@ func (p *Plugin[T]) AddCommand(command *Command[T]) *Plugin[T] {
|
||||
}
|
||||
return p
|
||||
}
|
||||
if command.exec == nil {
|
||||
if p.logger != nil {
|
||||
p.logger.Warnf("command '%s' has a nil executor; skipping", command.command)
|
||||
}
|
||||
return p
|
||||
}
|
||||
if _, exists := p.commands[command.command]; exists && p.logger != nil {
|
||||
p.logger.Warnf("command '%s' already registered in plugin '%s'; overwriting", command.command, p.name)
|
||||
}
|
||||
@@ -78,6 +84,12 @@ func (p *Plugin[T]) AddPayload(command *Command[T]) *Plugin[T] {
|
||||
}
|
||||
return p
|
||||
}
|
||||
if command.exec == nil {
|
||||
if p.logger != nil {
|
||||
p.logger.Warnf("payload '%s' has a nil executor; skipping", command.command)
|
||||
}
|
||||
return p
|
||||
}
|
||||
if _, exists := p.payloads[command.command]; exists && p.logger != nil {
|
||||
p.logger.Warnf("payload '%s' is already registered in plugin '%s'; overwriting", command.command, p.name)
|
||||
}
|
||||
@@ -153,6 +165,12 @@ func (p *Plugin[T]) UsePolicy(name string, policy Policy[T]) *Plugin[T] {
|
||||
// AddUpdateHandler registers a handler for a non-command update type.
|
||||
// Message, channel post, and callback query updates stay on the command/payload flow.
|
||||
func (p *Plugin[T]) AddUpdateHandler(t tgapi.UpdateType, handler CommandExecutor[T]) *Plugin[T] {
|
||||
if handler == nil {
|
||||
if p.logger != nil {
|
||||
p.logger.Warnf("update handler '%s' has a nil executor; skipping", t)
|
||||
}
|
||||
return p
|
||||
}
|
||||
switch t {
|
||||
case tgapi.UpdateTypeMessage, tgapi.UpdateTypeChannelPost, tgapi.UpdateTypeCallbackQuery:
|
||||
if p.logger == nil {
|
||||
@@ -255,7 +273,7 @@ func (p *Plugin[T]) executeCmd(cmd string, ctx *MessageContext, db T) error {
|
||||
}
|
||||
|
||||
// Execute command
|
||||
return command.exec(ctx, db)
|
||||
return callCommandExecutor(command.exec, ctx, db)
|
||||
}
|
||||
|
||||
func (p *Plugin[T]) executePayload(payload string, ctx *MessageContext, db T) error {
|
||||
@@ -276,7 +294,19 @@ func (p *Plugin[T]) executePayload(payload string, ctx *MessageContext, db T) er
|
||||
}
|
||||
|
||||
// Execute payload
|
||||
return command.exec(ctx, db)
|
||||
return callCommandExecutor(command.exec, ctx, db)
|
||||
}
|
||||
|
||||
func callCommandExecutor[T AppData](executor CommandExecutor[T], ctx *MessageContext, db T) (err error) {
|
||||
if executor == nil {
|
||||
return ErrHandlerExecutorNil
|
||||
}
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
err = fmt.Errorf("%w: %v", ErrHandlerPanic, recovered)
|
||||
}
|
||||
}()
|
||||
return executor(ctx, db)
|
||||
}
|
||||
|
||||
func (p *Plugin[T]) executeMiddlewares(ctx *MessageContext, db T) bool {
|
||||
@@ -343,14 +373,23 @@ func (m Middleware[T]) Execute(ctx *MessageContext, db T) bool {
|
||||
go func(ctx MessageContext) {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
reportMiddlewareError(&ctx, m.name, fmt.Errorf("middleware %q panicked: %v", m.name, recovered))
|
||||
reportMiddlewareError(&ctx, m.name, fmt.Errorf("%w in middleware %q: %v", ErrHandlerPanic, m.name, recovered))
|
||||
}
|
||||
}()
|
||||
m.executor(&ctx, db)
|
||||
}(ctxCopy)
|
||||
return true
|
||||
}
|
||||
return m.executor(ctx, db)
|
||||
result := false
|
||||
func() {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
reportMiddlewareError(ctx, m.name, fmt.Errorf("%w in middleware %q: %v", ErrHandlerPanic, m.name, recovered))
|
||||
}
|
||||
}()
|
||||
result = m.executor(ctx, db)
|
||||
}()
|
||||
return result
|
||||
}
|
||||
|
||||
func reportMiddlewareError(ctx *MessageContext, name string, err error) {
|
||||
|
||||
Reference in New Issue
Block a user